Reputation: 1201
I have to admit my C++ is a bit rusty. In a project I try to create a vector of classes and use them. There is a problem because I want to identify each entry of the vector with a unique pointer to it for fast access but it does not work. Here is a minimal example of my problem:
#include <iostream>
#include <vector>
class Foo{
public:
Foo() { ptr = this; }
~Foo() {}
Foo * ptr;
};
int main()
{
std::vector<Foo> vec;
for(unsigned int i = 0; i < 2; ++i)
vec.push_back(Foo());
for(unsigned int i = 0; i < vec.size(); ++i)
std::cout << "Object Self-Pointer: " << std::hex << reinterpret_cast<unsigned int>(vec[i].ptr) << std::endl;
}
Actual output:
Object Self-Pointer: bfbebc18
Object Self-Pointer: bfbebc18
Intended output:
Object Self-Pointer: bfbebc18
Object Self-Pointer: bfbebc1c
(some pointers to the actual objects).
I hope you can help me with this issue, thank you in advance.
Upvotes: 2
Views: 11492
Reputation: 8815
As others have mentioned, the problem is that push_back
pushes a copy of the object onto the stack, which is created using the copy constructor, which does a memberwise copy of the member variable.
One way to address this would be to define a copy constructor to do what you want; e.g.:
Foo(const Foo& rhs) { ptr = this;}
Running with this, I got the output:
Object Self-Pointer: 4b0308
Object Self-Pointer: 4b030c
Upvotes: 1
Reputation: 675
std::vector stores copies of the object (it is a requirement that type of object is copy-constructable). In this case, Foo's copy-constructor is auto generated by the compiler.
So when you do push_back(Foo()), you're doing:
1) Create a Foo() object. Set ptr to bfbebc18
2) Copy it, and put it into vector<Foo>
3) Delete the original Foo from which it came
4) Create a new Foo() object. Set ptr to bfbebc18 (the same location is used because it's temporary)
5) Copy it and put it into vector<Foo>
Upvotes: 3
Reputation: 122001
When you call push_back(Foo())
an object is constructed and then vector
will take a copy of that object. As Foo
is using the default copy constructor it will store the this
pointer of the temporary object created by Foo()
. The address of the temporary object appears to be the same in both iterations of the loop.
Upvotes: 1
Reputation: 4407
When you do this:
vec.push_back(Foo());
A new temporary Foo
object is created, but each time it is created in the same address (because it is created on stack and the stack pointer is the same). So the this
pointer, and therefore the ptr
member of each of these instances is the same.
When you add each instance to the vector, the default copy constructor is called, so the ptr
member is copied, and therefore all instances in the vector have the same value.
Upvotes: 10