我想知道下面的代码是否格式正确
if ( nChildLines == 0 )
{
nChildLines = 1;
Tag tempTag = attachmentlines.tag();
cfgChildLines = &tempTag;
}
这里,tampTag 是一些对象。 cfgChildLines 是指向在“if” block 之外声明的对象的作用域指针。
现在我的问题是,当“if” block 完成时,tempTag 会被破坏吗?如果是这样,指向 tempTag 的“cfgChildLines”的使用在 if block 结束后是否有效?
最佳答案
重要的是要记住,在 C++ 中获取地址并不能保证该地址继续指向有效内容的任何保护。语言中没有内置引用计数(这就是为什么我们必须发明 scoped_ptr/shared_ptr 等)。
牢记这一点,我们可以更详细地了解您的情况:
tempTag
是一个自动变量,在它创建的范围结束时被销毁。因此,您获取的地址将指向堆栈中某处指向此范围之外的已销毁对象。由于您分配给了一个 scoped_ptr,并且 scoped_ptr 假定它可以通过删除销毁对象,来自 the documentation
The scoped_ptr class template stores a pointer to a dynamically allocated object
(强调我的)
所以你违反了 scoped_ptr 的接口(interface),一旦 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
如果您确实需要更大范围内的 tempTag,那么只需在您需要的更大范围内声明它,不要使用 scoped_ptr。
void Foo()
{
Tag tempTag
{
nChildLines = 1;
tempTag = attachmentlines.tag();
}
}
另一种思考方式:当您创建一个动态分配的对象时,您就拥有了它的生命周期。您手动创建和销毁事物。因此,您可以将此所有权传递给另一个对象,例如可以为您管理事物的 scoped_ptr。相反,在堆栈上创建的变量将自动分配和释放——创建和销毁的权利完全由调用堆栈持有,您不能将这些权利授予自己或其他人(即 scoped_ptr)。您只能策略性地将这些变量放在正确限定变量范围的位置,以便自动的、基于堆栈的生命周期与您打算如何使用这些东西相对应。
关于c++ - 在我的代码中,scoped_ptr 指向一个堆栈变量——这会延长堆栈变量的生命周期吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7320122/