我来自C#背景到C ++。假设我有一个方法在堆栈的方法中创建一个对象,然后我将它传递给另一个类方法,该方法将它添加到一个memeber向量。
void DoStuff()
{
SimpleObj so = SimpleObj("Data", 4);
memobj.Add(so);
}
//In memobj
void Add(SimpleObj& so)
{
memVec.push_back(so); //boost::ptr_vector object
}
以下是我的问题:
我意识到这些对C ++程序员来说可能是显而易见的。
标记
答案 0 :(得分:9)
实现您尝试执行的操作的最简单方法是将对象的副本存储在普通STL容器中(例如std::vector
)。如果这些对象是重量级的并且复制成本很高,那么您可能希望在堆上分配它们将它们存储在具有足够智能指针的容器中,例如, boost::shared_ptr
(请参阅@Space_C0wb0y's answer中的示例)。
另一种可能性是将boost::ptr_vector
与boost::ptr_vector_owner
结合使用;最后一个类负责“拥有”存储在关联的ptr_vector
中的对象,并在超出范围时删除所有指针。有关ptr_vector
和ptr_vector_owner
的详细信息,您可能需要查看this article。
答案 1 :(得分:3)
要实现目标,您应该使用shared_ptr:
void DoStuff()
{
boost::shared_ptr<SimpleObj> so(new SimpleObj("Data", 4));
memobj.Add(so);
}
//In memobj
void Add(boost::shared_ptr<SimpleObj> so)
{
memVec.push_back(so); // std::vector<boost::shared_ptr<SimpleObj> > memVec;
}
答案 2 :(得分:1)
是的,一旦你的函数离开范围,你的对象就会从堆栈中弹出。您应该使用new
创建一个堆对象,并在向量中添加一个指针。
如前所述,当你的第一个函数超出范围时,向量中的指针将指向未定义的东西
答案 3 :(得分:1)
该代码无法编译,因为在Add函数中,您试图将整个对象推送到需要指向对象的指针的向量中。
如果您要获取该对象的地址并将其推送到向量上,那么这将是危险的,因为原始对象很快将从堆栈中弹出,并且您存储的指针将指向未初始化的内存。 / p>
如果你使用普通向量而不是指针向量,则push_back调用将复制整个对象而不是指针,因此它是安全的。但是,这并不一定有效,对于来自C#,Java或Python世界的人来说,“复制一切”方法可能并不直观。
答案 4 :(得分:0)
为了存储指向对象的指针,必须使用new创建它。否则它会在超出范围时消失。
这里介绍的问题最简单的解决方案是使用std :: vector而不是boost :: ptr_vector,因为这样push_back会复制向量中的对象