在这个shared_ptr示例中有一些不清楚的地方
Something unclear in this shared_ptr example
#include <iostream>
#include <boost/shared_ptr.hpp>
class implementation
{
public:
~implementation() { std::cout <<"destroying implementationn"; }
void do_something() { std::cout << "did somethingn"; }
};
void test()
{
boost::shared_ptr<implementation> sp1(new implementation());
std::cout<<"The Sample now has "<<sp1.use_count()<<" referencesn";
boost::shared_ptr<implementation> sp2 = sp1;
std::cout<<"The Sample now has "<<sp2.use_count()<<" referencesn";
sp1.reset();
std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" referencesn";
sp2.reset();
std::cout<<"After Reset sp2.n";
}
int main()
{
test();
}
运行结果如下:
$ ./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,我对吗?
我不明白的第一件事是下面的句子是什么意思?sp1是一个指针?一个函数?还是指向函数的指针?
sp
是shared_ptr<implementation>
。如果您不知道这是什么意思,可以参考参考文档和教程。但简短的版本是:它是一个类似于implementation *
指针的对象,除了它会在完成implementation
对象时自动删除它。这就是为什么它是一个"智能指针"。shared_ptr
是一种特定类型的智能指针,它允许您创建任意数量的副本,并且仅在所有副本消失时才删除底层对象。
这样做的一种方式是,它提供了一种简单形式的垃圾收集,不需要垃圾收集器。
另一种看待它的方式是作为资源获取即初始化(RAII)的一部分,RAII是c++的中心习惯用法之一。
和new implementation()意味着什么?sp1()的参数?
new implementation()
创建一个新的implementation
对象,调用其默认构造函数,并返回一个implementation *
指针。该指针是shared_ptr
构造函数的实参。这意味着sp1
成为指向新的implementation
对象的智能指针,因此当sp1
和后来对它的任何副本都消失时,该对象将被销毁和删除。
第二个问题是销毁实现是sp1.reset()和sp1.reset()的结果。
实际上,它是sp1
和sp2
指向新值或被销毁的结果。reset
做了前者,但只是什么都不做,让他们离开范围做了后者。这是RAII的一个主要部分。
所以没有必要调用sp1.reset()和sp1.reset()来释放shared_ptr,我对吗?
。很少需要显式调用reset
。RAII的要点在于你不需要手动管理这些东西;你初始化一个对象(比如shared_ptr
)来获得对资源的访问权,然后让这个对象离开来释放访问权。
在一些情况下它是有用的。例如,如果您有一个shared_ptr
作为对象的成员,并且该对象将持续比它拥有的资源长得多的时间,您可以通过调用reset
提前释放它。(如果你在此期间把副本传给了别人,你不必担心它会被提前删除——这只意味着你不再参与保持它的存在。)
正如在评论中指出的那样,有一些基础知识需要从SO格式中学习。
然而,最后一个问题值得回答:
所以没有必要调用sp1.reset()和sp1.reset()来释放shared_ptr,我对吗?
如果您只重置一个指针,则您看到实现被破坏的原因是由于作用域结束,即从test()
返回-导致shared_ptr
s超出作用域并被销毁,从而导致托管对象的销毁。
- 关于隐式声明的复制构造函数的引用在逻辑上不清楚
- C++复制 c'tor 现在确实会采取行动。 不清楚为什么
- 矢量编程:不清楚矢量的初始化
- 调用虚函数的逻辑不清楚(或者是方法隐藏?
- cudaMemcpy 在从设备读取到主机时返回 cudaErrorInvalidArgument,不清楚原因
- 实现附加对象:不清楚的文档示例
- 智能指针移动语义我不清楚
- 在 c++ 中移动 2d 数组的构造函数(语法逻辑不清楚):
- 为什么这个错误如此不清楚
- 在特定情况下,指针删除和铸造之间的关系不清楚
- 切换语句在 C++ 中的输出不清楚
- 不清楚的副本分配操作员示例
- 我在c++应用程序上搞不清楚
- Visual Studio 2012 中的错误日志不清楚
- C++引用-有些事情我不清楚
- 解密不清楚的语法
- 使用Boost Coroutine(1.55)的不清楚分割错误
- 不清楚按位 AND 赋值的使用
- 纹理不清楚的 OpenGL 渲染
- 不清楚如何在从抽象基类派生的类中实现运算符重载