2012-05-24 42 views
8

scoped指针的目标是什么?据我了解,范围指针管理一块代码中的内存。如果我想在一个块内声明一个变量,我可以在堆栈中声明它,而不用担心清理。为什么scoped指针在提升

+0

http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm#Handle/Body –

回答

1

问题是你可以创建和清理某个词法范围内的指针。这可以在各种情况下有用,并且它可以确保您没有内存泄漏,如果您明确使用new,则忘记delete,这不被推荐。

您应该记住,boost::scoped_ptr不可复制的,因此在整个生命周期中它完全拥有它的资源。这也使得它更安全,然后boost::shared_ptr,因为它避免了复制资源或意外分享资源。

{ //Some Scope 

    boost::scoped_ptr<int> i_ptr; 
    // do something with pointer 

} // leave scope, pointer is cleaned up 
4

如果是动态尺寸或类型,则不适用。另外,范围指针可以交换,并且在C++中可以移动,所以它们不是严格限定范围的。

+1

除了“主要理由使用'scoped_ptr'而不是'auto_ptr'就是让你的代码的读者知道你打算“资源获取是初始化”仅仅适用于当前的范围,并且没有意图转移所有权“......看起来像'swap '不是一个预期的用法。 –

+0

@BenVoigt:但它提供并可以使用。 – Puppy

+2

这是[一个旧线程](http://lists.boost.org/Archives/boost/2002/09/36359.php)讨论为什么'swap'成为一个需求(基本上这样'scoped_ptr'可以用作成员可复制课程)。 –

0

通常线程堆栈有内存限制(请参阅线程堆栈大小)。

有时指针可能已从外部传递给您,并且需要在此范围内删除(例如,如果抛出异常,则该行下方的任何删除调用都不会执行)。因此,你需要某种方式的自动神奇地清理指针

void foo(Object*obj) 
{ 
    //this will ensure that object gets cleaned up even if doFoo() throws an exception 
    boost::scoped_ptr<Object> objCleaner(obj); 
    obj->doFoo(); 
} 
+0

我可以在堆栈上声明指针,当函数超出作用域时,它会自动清除,无论是成功还是异常。正确? – Jimm

+0

{X * x =&someObj; }这不会导致指针x在超出范围时被删除。 someObj在超出范围时将被删除。 {X * y = new X();}这种类型的代码将需要scoped ptr来自动清理 – mohaps

2

与基于堆栈的数据,使用scoped_ptr有一个复位()成员 - 换句话说,你可以构建/毁灭你的心脏的内容。有了这个,你可以使用一个空指针(技术上为operator unspecified-bool-type)作为一个标志,指示在任何给定时间是否有构造对象。如果需要,它还允许您独立于变量范围对构建/销毁进行排序。

另外,考虑到你可以声明一个scoped_ptr作为一个类成员,而不仅仅是一个堆栈变量。 docs建议使用scoped_ptr来实现句柄/正文表达式(隐藏类的实现细节)。

最后,阐述DeadMG的观点“不,如果它是动态类型的”,你可以使用scoped_ptr的实现polymorphic操作:

{ 
scoped_ptr<Base> a(mode ? new DerivedA : new DerivedB); 
a->polymorphic_function(); 
} 

这不是真的有可能与简单重新建立了新来做到这一点基于分配。


而且在这里看到:C++0x unique_ptr replaces scoped_ptr taking ownership?

+0

'boost :: variant '。 :) – GManNickG

+0

@GManNickG:我不认为boost :: variant通过scoped_ptr为多态提供了一个很好的替代 - 虽然有趣。谢谢! – nobar

+0

你为什么不这么认为? – GManNickG