C ++自引用类

时间:2012-03-08 21:03:39

标签: c++ stl vector

我必须承认我的C ++有点生疏。在一个项目中,我尝试创建一个类向量并使用它们。有一个问题,因为我想识别向量的每个条目,并带有一个唯一的指针,以便快速访问,但它不起作用。这是我的问题的一个最小例子:

#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; 
}

实际输出:

Object Self-Pointer: bfbebc18
Object Self-Pointer: bfbebc18

预期输出:

Object Self-Pointer: bfbebc18
Object Self-Pointer: bfbebc1c

(指向实际对象的一些指针)。

我希望你能帮我解决这个问题,提前谢谢你。

4 个答案:

答案 0 :(得分:10)

执行此操作时:

vec.push_back(Foo());

创建一个新的临时Foo对象,但每次在同一地址创建它(因为它是在堆栈上创建的,堆栈指针是相同的)。因此,this指针以及每个实例的ptr成员都是相同的。

将每个实例添加到向量时,将调用默认的复制构造函数,因此会复制ptr成员,因此向量中的所有实例都具有相同的值。 / p>

答案 1 :(得分:3)

std :: vector存储对象的副本(要求对象类型是可复制构造的)。在这种情况下,Foo的拷贝构造函数由编译器自动生成。

所以当你做push_back(Foo())时,你正在做:

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>

答案 2 :(得分:1)

当您调用push_back(Foo())时,会构造一个对象,然后vector将获取该对象的副本。当Foo使用默认的复制构造函数时,它将存储由this创建的临时对象的Foo()指针。在循环的两次迭代中,临时对象的地址看起来都是相同的。

答案 3 :(得分:1)

正如其他人所提到的,问题是push_back将对象的副本推送到堆栈上,该堆栈是使用复制构造函数创建的,复制构造函数执行成员的成员副本变量

解决这个问题的一种方法是定义一个复制构造函数来做你想做的事情; e.g:

Foo(const Foo& rhs) { ptr = this;}

运行这个,我得到了输出:

Object Self-Pointer: 4b0308
Object Self-Pointer: 4b030c