C++ Passing two dimensional arrays as parameters to classes
I've got a Car class and a Track class. The Car class constructor takes a road 开发者_如何学运维parameter which is supposed to be a 32x32 boolean array. Then I've got a Track class which creates a Car class and is supposed to pass the 32x32 array to it's constructor.
Note that I've simplified the code somewhat by removing irrelevant bits and pieces.
class Car : public WorldObject
{
private:
bool _road[32][32];
public:
Car(bool road[32][32])
{
_road = road;
}
};
class Track : public WorldObject
{
public:
bool _road[32][32];
Track()
{
Car* _car = new Car(this->_road);
_car->Position.X = 50;
_car->Position.Y = 50;
ChildObjects.push_back(_car);
}
};
This won't compile ... I get an error:
Error 1 error C2440: '=' : cannot convert from 'bool [][32]' to 'bool [32][32]'
in the the _road = road; line in the Car constructor.
What am I doing wrong?
In C/C++ every parameter is passed by value except arrays - they are passed by reference. This means in your situation: The signature of your constructor must be read like this:
Car(bool (*road)[32]);
This means: road
is a pointer to an array of 32 booleans (to get further informations please read litb's answer to a related question.) Now if you write
_road = road
you copy the value of the pointer road
to the variable _road
. This is rejected by your compiler because _road
isn't a pointer, it's an array of arrays of booleans. For more information about arrays and their values read this. To solve this situation you have to copy the elements of _road
manually to road
. Something like the following code would solve your problem:
for (int i=0;i<32;++i)
for (int j=0;j<32;++j)
_field[i][j] = field[i][j];
To give a minimalistic answer, the only thing that your are doing wrong is that you are trying to assign one array to another array. It really has noting to do with any "passing", as you seem to believe (judging by the subject of your question).
(Yes, I know, the RHS in that problematic assignment is not really an array, but that is a different story).
Remember, in C++ arrays are not assignable and not copy-constructible. For example, this code
int a[10], b[10] = {};
a = b;
is ill-formed for exacly the same reason. You can't assign arrays, regardless of whether you are "passing" them somewhere or not.
The compiler will normally respond with an error message that will involve pointers, which is a consequence of so called "array type decay", which other have already mentioned in previous replies (read up on it).
Since you can't assign arrays, in order to copy your array in this case you either need to do it manually, element by element as in
for (i = 0; i < 32; ++i)
for (j = 0; j < 32; ++j)
_road[i][j] = road[i][j];
or you can use 'memcpy' in a few different wys
1. memcpy(_road, road, 32 * 32 * sizeof **_road);
2. memcpy(_road, road, 32 * sizeof *_road);
3. memcpy(_road, road, sizeof _road);
There are more alternative ways to do it.
Note that the aforementioned "array type decay" does take place in this case (as always), but it is transparent to you, i.e. if you perform manual per-element copying you don't need to wory about it al all, as illustrated by the above examples.
You can't copy arrays like that. Others have already discussed this in more detail, including alternative for-loop individual assignment and memcpy solutions.
Another solution is to wrap your array inside a struct. Struct's can be copied like that.
E.g.:
struct RoadStruct
{
bool road[32][32];
};
class Car : public WorldObject
{
private:
RoadStruct _road;
public:
Car(const RoadStruct & road )
{
_road = road;
}
};
Though it would be more efficient to copy like this:
public:
Car(const RoadStruct & road )
: _road ( road )
{}
(Of course that creates 2 RoadStruct data sets. If you only wanted one shared array, that could be arranged...)
In C++, you can use the standard library to get arrays with more functionality than bool var[n]
. Try vector< vector< bool > > road( 32, 32 );
This will be an object that you can pass to functions and assign as you like.
However, conceptually, you might think about linking the _road
data from Track
to Car
rather than copying it, with a vector< vector< bool > > const &_road;
and
public:
Car( vector< vector< bool > > const &road )
: _road = road;
{
}
};
Constructor:
Passing an array to constructor in your code is valid. But here is a small problem to take care, you can pass any two dimensional array of type bool with raw size 32. That is your member variable Track::_road shall not produce any error even if it is declared as bool _road[16][32]; This may lead to a memory exception. To avoid this problem, you should specify the function parameter as a reference to an array of dimension 32x32 as follows.
Car(bool (&road)[32][32])
{
}
You may access values inside your function as follows.
_road[i][j] = road[i][j];
You can create a new instance of your class as follows.
Car* _car = new Car(this->_road);
Assignment:
In C/C++, you cannot directly copy an array to another array. You have to copy each and every element individually. You may use a for loop as follows, or some library functions for copying.
for( i = 0; i < 32; i++ )
{
for( j = 0; j < 32; j++ )
{
_road[i][j] = road[i][j];
}
}
bool road[32][32] is invalid.
There should be a comma in there or the bool should be removed.
精彩评论