用静态或全局对象初始化共享指针

时间:2018-12-01 11:06:56

标签: c++ shared-ptr

以下代码显示使用全局或静态对象的地址初始化共享对象不正确,因为当共享指针超出范围时,将删除全局对象。

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教程中看到了以下代码片段 (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是一个整体或静态变量。是不是当上述流共享指针超出范围时,为什么不构成被销毁的风险? 请说明一下。 谢谢

3 个答案:

答案 0 :(得分:1)

通过链接null_deleter:boost :: null_deleter函数对象可以用作带有智能指针(例如unique_ptr或shared_ptr)的删除器。删除器对释放后提供的指针不执行任何操作,这在将指向对象释放到其他位置时非常有用。

换句话说,使用null_deleter,智能指针将永远不会尝试删除指向的对象。

答案 1 :(得分:0)

如果您提供一个不会试图销毁并释放它的删除器,那是合法的。

shared_ptr接受两个参数(检查documentation):地址和删除器。 Deleter参数是可选的。

默认的删除器(即,当您不明确提供删除器时使用的删除器)会破坏对象并释放堆,因此它显然不适用于堆上没有的任何东西。

答案 2 :(得分:0)

有两种选择:

  1. 使用nop-deleter。只需接受该虚假控制块的开销即可。

  2. 使用别名构造函数。 std::weak_ptr s不能使用。
    请参阅“ Using C++ shared pointer's aliasing constructor with an empty shared pointer ”。