在我的代码中,scoped_ptr指向一个堆栈变量 - 这是否延长了堆栈变量的生命周期?

Pav*_*avi 2 c++ boost pointers

我想知道以下代码是否格式正确

 if (  nChildLines == 0 ) 
 {
    nChildLines = 1;
    Tag tempTag = attachmentlines.tag();
    cfgChildLines = &tempTag;
 }
Run Code Online (Sandbox Code Playgroud)

在这里,tampTag是一些对象.cfgChildLines是指向'if'块之外声明的对象的作用域指针.

现在我的问题是,当'if'块完成时,tempTag会被破坏吗?如果是这样,指向tempTag的'cfgChildLines'的使用是否有效超过if块的结尾?

Dou*_* T. 5

重要的是要记住,在C++中使用地址并不能保证该地址继续指向有效的保护.语言中没有引用计数(这就是为什么我们必须发明scoped_ptr/shared_ptr/etc).

记住这一点,我们可以在您的情况下更详细地查看:

tempTag是一个自动变量,并在创建它的范围的末尾被销毁.因此,您所使用的地址将指向堆栈中的某个位置,以指向此范围之外的已销毁对象.由于您已分配给scoped_ptr,并且scoped_ptr假定它可以通过删除从文档中销毁对象

scoped_ptr类模板存储指向动态分配对象的指针

(强调我的)

因此,您违反了scoped_ptr的界面,并且一旦删除了scoped_ptr,您将会遇到一些未定义的行为.

 {
    nChildLines = 1;
    Tag tempTag = attachmentlines.tag();
    cfgChildLines = &tempTag;
 } // tempTag destroyed here


// LATER
} // scoped_ptr calls delete, undefined behavior possibly crash, 
  // possibly an occasional crash
Run Code Online (Sandbox Code Playgroud)

如果你真的需要更大范围内的tempTag,那么只需在你需要它的更大范围内声明它,不要使用scoped_ptr.

void Foo()
{
   Tag tempTag 

    {
        nChildLines = 1;
        tempTag = attachmentlines.tag();
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种思考方式:创建动态分配的对象时,您将获得其生命周期的所有权.您手动创建并销毁该东西.因此,您可以将此所有权传递给另一个对象,例如可以为您管理的scoped_ptr.相反,在堆栈上创建的变量将被自动分配和释放 - 创建和销毁的权限完全由调用堆栈保存,您不能将这些权限赋予自己或其他人(即scoped_ptr).您只能策略性地将这些变量放在一个正确范围变量的位置,以便基于堆栈的自动生命周期与您打算使用该事物的方式相对应.