我需要在C ++中存储对派生类实例的引用。我考虑过将shared_ptrs的向量用于基类(因为它需要保存不同类型的派生类),但是,容器保存原始指针很重要,而矢量(或其他stl容器)不是这种情况,如果我没错的话。有没有办法在本机C ++中执行此操作,还是必须使用Boost的ptr_vector等特殊容器?
编辑:这是我的测试代码:
class Foo
{
public:
Foo() {}
virtual ~Foo() {}
virtual void set_x(int i) = 0;
};
class Bar : public Foo
{
public:
Bar() {}
void set_x(int i)
{
this->x = i;
}
int x;
};
int main()
{
Bar bar;
// ptr
std::cout << &bar << "\n";
std::vector<Foo*> foos;
foos.push_back(&bar);
// different ptr value
std::cout << &foos[0] << "\n";
foos[0]->set_x(1);
// however, changes are made
std::cout << bar.x;
return 0;
}
提前致谢,
Jena的
答案 0 :(得分:1)
您可以创建一个std :: vector&lt; foo *&gt;,它将保存指向foo的任何指针。它不会尝试删除那些破坏上的指针,这些指针可能是你想要的,也可能不是你想要的,但它会完全保留你传入的值。
您还可以创建一个std :: vector&lt;的shared_ptr&LT; FOO&GT; &gt;,它将保存指针,一旦没有浮动的shared_ptr的悬空副本就会被释放。那些也将保存你传入的“原始”foo *;您可以使用shared_ptr :: get()方法再次获取它。
如果您使用多个类继承,并且您的基类包含数据,那么您唯一一次看不到与派生对象完全相同的指针。因为foo *会结束,在这种情况下,指向数据的“foo”部分,这不一定是对象的“根”。
答案 1 :(得分:1)
在上面的示例中,您要打印的是指针的地址而不是指针的值。
而不是:
// different ptr value
std::cout << &foos[0] << "\n";
做
// different ptr value
std::cout << foos[0] << "\n";
除此之外,您vector<Foo*>
的效果会很好。
答案 2 :(得分:0)
如果使用shared_ptr
作为容器成员,则每个成员中的指针将保留对原始对象实例的访问权限。您可以在容器内务管理后的任何时候获得shared_ptr
的副本,但原始对象仍然是其目标。
对于更简单的解决方案,您可以使用boost::ptr_vector
,前提是您的指针中没有任何指针在容器中出现两次 - 这种情况会引入棘手的资源管理复杂性并指向shared_ptr
。