在堆栈上创建一个对象,然后通过引用传递给C++中的另一个方法

Mar*_*ark 6 c++ gcc boost memory-management

我来自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
}
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

  1. 一旦DoStuff方法结束,那么会超出范围并从堆栈中弹出?
  2. memVec有一个指向这样的指针,但它弹出了这里发生的事情?
  3. 什么是将堆栈对象传递给将它们存储为指针的方法的正确方法?

我意识到这些对C++程序员来说可能是显而易见的.

标记

Mat*_*lia 9

  1. 是.
  2. 指针保持"活着",但指向不再存在的对象.这意味着,当您第一次尝试取消引用此类指针时,您将进入未定义的行为(可能您的程序将崩溃,或者更糟糕的是,将继续运行给出"奇怪"结果).
  3. 如果要在返回函数后保留它们,则根本不这样做.这就是使用堆分配和存储对象副本的容器的原因.

实现您要做的事情的最简单方法是将对象的副本存储在普通的STL容器中(例如std::vector).如果这些对象重量级且复制成本很高,您可能希望在堆上分配它们将它们存储在具有足够智能指针的容器中,例如boost::shared_ptr(参见@ Space_C0wb0y的答案中的示例).

另一种可能性是与... boost::ptr_vector结合使用boost::ptr_vector_owner; 最后一个类负责"拥有"存储在关联中的对象ptr_vector,并在超出范围时删除所有指针.有关详细信息ptr_vector,并ptr_vector_owner,你可能想看看这篇文章.

  • 在C++ 0x中,我建议使用`std :: vector <std :: unique_ptr <T >>`这是一个异常安全,低开销,自动内存管理的容器,它可能会做你想要的一切,而且更好比boost :: ptr_vector(IIRC不适用于某些STL算法). (3认同)