【发布时间】:2018-12-01 21:38:25
【问题描述】:
以下代码显示使用全局或静态对象的地址初始化共享对象是不正确的,因为当共享指针超出范围时,全局对象会被删除。
class Dog() {
public:
void bark() {
cout << "Dog barks" << endl;
}
};
Dog g_Dog;
void test() {
shared_ptr<Dog> myDog(&g_Dog);
myDog->bark();
}
int main() {
test();
}
上面的代码崩溃了。我的理解是我们不应该用静态或全局对象初始化共享指针,而应该只对堆中的对象这样做。对吗?
我在 boost log 教程中看到了以下代码 sn-p (https://www.boost.org/doc/libs/develop/libs/log/doc/html/log/tutorial/sinks.html)
#include <boost/core/null_deleter.hpp>
// We have to provide an empty deleter to avoid destroying the global stream object
boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());
sink->locked_backend()->add_stream(stream);
你们能解释一下代码的原因吗
boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());
不会造成任何问题。看起来 std::clog 是一个全局变量或静态变量。不是吗?当上面的流共享指针超出范围时,为什么它不会造成被破坏的风险。 请阐明一些观点。 谢谢
【问题讨论】:
-
您的问题的答案就在代码中:“我们必须提供一个空的删除器以避免破坏全局流对象”
-
谢谢。当我在 boost 中检查 null_deleter 时,它是一个结构,其操作符 () 实现如下。模板 void operator() (T*) const BOOST_NOEXCEPT {} 。您能否解释一下为什么在上面的代码中可以通过调用 boost::null_deleter() 来启动结构的实例,而不是仅仅将结构本身作为 boost::null_deleter 提供,它在共享指针初始化中接受 lambda
-
这叫做函子。
-
请不要在 cmets 中提问或添加信息,而是编辑您的问题。 null_deleter 只是一个空操作。它什么也没做。因此,当共享指针计数器变为 0 时,
std::clog不会被删除。 -
为什么首先要将指向全局对象的指针存储在
shared_ptr中?shared_ptr用于共享所有权,全局变量不归任何人所有,无论如何都是“共享”的
标签: c++ shared-ptr