My basic program structure is this:
class B1
{
vector <someStruct> aStruct; //some struct contains a vector of 'someotherStruct's, etc
B1() { cout << &aStruct << " ";};
};
class B2 {B1* pB1;};
class A
{
B1 object_B1;
B2 object_B2;
A() { objectB2.pB1 = &object_B1;};
开发者_运维百科};
int main()
{
vector <A> someA;
for(int q=0; q < N; q++)
someA.push_back(A());
cout << endl;
for (int q=0; q < N; q++)
cout << someA[q].B2.pB1 << " ";
}
So if N was 5, the output would be: 0xbffff828 0xbffff828 0xbffff828 0xbffff828 0xbffff828 \n
0xbffff828 0xbffff828 0xbffff828 0xbffff828 0xbffff828In other words, each object's vector occupies the same space in memory. And program output bears this out as well, since accessing data in the vector through different objects gives the same values, even when they should be different. The other weird thing, of course, is it gives me the same address for the vector as for the object.
Ignoring the large number of errors in the program...
A.push_back(A());
This creates a temporary object of type A
. The object_B2.pB1
member variable is initialized to point to the object_B1
member variable of this temporary object.
This temporary A
object is then copied into the someA
container. The address of this copy's object_B1
member variable is different, but you don't update the object_B2.pB1
member variable to point into the new instance. To do this, you would need to implement a copy constructor (and, for correctness, you would also need to implement a copy assignment operator).
The reason that all of the pointers end up being the same is that the temporary objects are all created in the same location in memory, which makes since, since you are presumably calling push_back
in a loop, so the temporary object can be created on the stack in the same place at each iteration through the loop.
You are missing a copy ctor for A and the default copy semantics copy the pointer value from one B2 object to another. Each item in the struct sees the same address because they are all copied from the same source object. When this pointed-to object is later destroyed, you'll have UB accessing it.
A a1;
A a2 = a1;
assert(a2.object_B2.pB1 == &a1.object_B1); // Danger Will Robinson!
The fix:
struct A {
B1 object_B1;
B2 object_B2;
A() { objectB2.pB1 = &object_B1; }
A(A const &x)
: object_B1 (x.object_B1)
{
object_B2.pB1 = &object_B1;
}
};
You also need a copy-assignment operator because the default one has a similar problem. Declare this op= as private without defining it if you want it disabled.
精彩评论