2013-01-01 28 views
1
#include <iostream> 
#include <boost/shared_ptr.hpp> 

class implementation 
{ 
public: 
    ~implementation() { std::cout <<"destroying implementation\n"; } 
    void do_something() { std::cout << "did something\n"; } 
}; 

void test() 
{ 
    boost::shared_ptr<implementation> sp1(new implementation()); 
    std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n"; 

    boost::shared_ptr<implementation> sp2 = sp1; 
    std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n"; 

    sp1.reset(); 
    std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n"; 

    sp2.reset(); 
    std::cout<<"After Reset sp2.\n"; 
} 

int main() 
{ 
    test(); 
} 

运行结果不清楚低于:东西在这个shared_ptr的例子

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 1 references 
destroying implementation 
After Reset sp2. 

请检查上面的代码。我不清楚的第一件事是,下面的句子是什么意思?所以sp1是一个指针?一个函数?或者一个指向函数的指针?和new implementation()意味着什么? sp1()的参数?

boost::shared_ptr<implementation> sp1(new implementation()); 

第二个问题是,destroying implementation给出的sp1.reset()sp2.reset()的结果。但是,如果sp1.reset()被注释掉,那么结果将是:

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 2 references 
After Reset sp2. 
destroying implementation 

如果我们只注释掉sp2.reset(),那么结果将是:

$ ./a.out 
The Sample now has 1 references 
The Sample now has 2 references 
After Reset sp1. The Sample now has 1 references 
After Reset sp2. 
destroying implementation 

所以没有必要同时调用sp1.reset()sp2.reset()释放shared_ptr,我是对不对?

+3

你不需要调用'reset'来释放指针**,你可以使用'reset'来改变智能指针当前指向的内容。您可以将它想象为一个常规指针的赋值运算符。 –

+5

如果你不知道'new x()'做了什么,你需要了解指针。如果你不知道共享指针是什么,你需要了解智能指针。没有简单的答案比实际阅读更有益。 – chris

+0

在试图理解C++'shared_ptr'之前,至少可以想象你应该先学习另一种语言。根据“Python自动执行的操作”或“在语言X中执行相同的操作'try'/ finally'执行相同的操作,这要比从头开始解释它要容易得多。” – abarnert

回答

2

我不清楚的第一件事是,下面的句子是什么意思?所以sp1是一个指针?一个函数?或者一个指向函数的指针?

spshared_ptr<implementation>。如果您不知道这意味着什么,那么请参阅参考文档和教程。但简短版本是:这是一个与implementation *指针类似的对象,只不过它会在您完成对象时自动删除implementation对象。这就是它成为“智能指针”的原因。 A shared_ptr是一种特定类型的智能指针,可让您根据需要制作任意数量的副本,并且只在所有这些副本都消失时才删除底层对象。

看起来像这样的一种方式是它为您提供了一种不需要垃圾回收器的简单垃圾回收形式。

查看它的另一种方法是作为C++中央成语之一​​(RAII)的一部分。

和新的实现()意味着什么? sp1()的参数?

new implementation()创建一个新implementation对象,调用它的默认构造函数,并返回一个指针implementation *。该指针是shared_ptr构造函数的参数。这意味着sp1成为一个智能指针,指向新的implementation对象,这样当sp1和其后的任何副本都会消失时,对象将被销毁和删除。

第二个问题是销毁实现是由sp1.reset()和sp2.reset()给出的。

事实上,它给出正指向新的价值被破坏双方sp1sp2的结果。reset做前者,但只是无所作为,让他们超出范围做后者。这是RAII的重要组成部分。

因此,不需要同时调用sp1.reset()和sp2.reset()来释放shared_ptr,对吗?

没错。你很少想明确地打电话给reset。 RAII的重点在于你不必手动管理这些东西;您初始化一个对象(如shared_ptr)以获取对资源的访问权限,并让该对象消失以释放访问权限。

有几种情况下,它是有用的。例如,如果您有一个shared_ptr作为对象的成员,并且该对象将持续比它拥有的资源长得多的时间,则可以通过调用reset提前释放该对象。 (如果您在此期间已将副本传递给其他人,则不必担心其被早期删除 - 这仅表示您不再参与保持活动状态。)

1

正如评论中指出的那样,从SO格式中学习一些基础知识。

然而,最后一个问题值得回答:

所以没有必要调用都sp1.reset()和sp2.reset()来释放shared_ptr的,对吗?

你看,如果你仅重置您的指针之一实施破坏的原因是由于范围结束,即从test()返回 - 使你的shared_ptr s到走出去的范围和被破坏,从而导致销毁管理对象。

+0

否,它是_not_“程序结束”,它是“范围末端'sp1'和'sp2'被定义在',这是'test'函数。如果'shared_ptr'没有删除对象直到程序结束,那么对它们的指向会少得多,因为当程序结束时所有的内存都会被释放。 (当然,这是“少点”,而不是“没有意义”,因为有时析构函数不仅仅是空闲的内存。) – abarnert

+0

@abarnert是的,你当然是对的。修复它。 – SomeWittyUsername