简体   繁体   English

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

[英]initializing a shared pointer with a static or global object

The following code shows initializing a shared object with the address of a global or static object is not right as the global object gets deleted when the shared pointer goes out of scope. 以下代码显示使用全局或静态对象的地址初始化共享对象不正确,因为当共享指针超出范围时,将删除全局对象。

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();

}

The above code crashes. 上面的代码崩溃。 My understanding is we should not initialize shared pointers with static or global object and should only do so with objects in the heap. 我的理解是我们不应使用静态或全局对象初始化共享指针,而应仅使用堆中的对象初始化共享指针。 Is that correct ? 那是对的吗 ?

I saw following code snippet in boost log tutorial ( https://www.boost.org/doc/libs/develop/libs/log/doc/html/log/tutorial/sinks.html ) 我在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);

Can you guys explain why the code 你们能解释为什么代码

  boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter()); 

does not cause any problem. 不会造成任何问题。 it looks like std::clog is aa glonal or a static variable. 它看起来像std :: clog是一个整体或静态变量。 Isn't it ? 是不是 why doesn't it pose the risk of getting destroyed when the above stream shared pointer goes out of scope. 当上述流共享指针超出范围时,为什么不构成被销毁的风险? Please shed some light. 请说明一下。 Thanks 谢谢

From the link null_deleter : boost::null_deleter function object can be used as a deleter with smart pointers such as unique_ptr or shared_ptr. 从链接null_deleter :boost :: null_deleter函数对象可以用作带有智能指针(例如unique_ptr或shared_ptr)的删除器。 The deleter doesn't do anything with the pointer provided upon deallocation, which makes it useful when the pointed object is deallocated elsewhere. 删除器对释放后提供的指针不执行任何操作,这在将指向对象释放到其他位置时非常有用。

In other words, using the null_deleter, the smart pointer will never try to delete the pointed object. 换句话说,使用null_deleter,智能指针将永远不会尝试删除指向的对象。

It's legal if you provide a deleter which won't attempt to destroy and free it. 如果您提供不会试图销毁和释放它的删除器,那是合法的。

shared_ptr takes two arguments (check the documentation ): the address and a deleter. shared_ptr带有两个参数(请参阅文档 ):地址和删除器。 Deleter argument is optional. Deleter参数是可选的。

The default deleter (ie the deleter used when you don't provide any explicitly) destroys the object and frees the heap, so it obviously won't work for anything not on the heap. 默认的删除器(即,当您不显式提供删除器时使用的删除器)会破坏对象并释放堆,因此它显然不适用于堆上没有的任何对象。

There are two options: 有两种选择:

  1. Use a nop-deleter. 使用nop-deleter。 Just accept the overhead of that spurious control-block. 只需接受该虚假控制块的开销即可。

  2. Use the aliasing constructor. 使用别名构造函数。 std::weak_ptr s won't work with it though. std::weak_ptr不能使用。
    See " Using C++ shared pointer's aliasing constructor with an empty shared pointer ". 请参阅“ 将C ++共享指针的别名构造函数与空的共享指针一起使用 ”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM