简体   繁体   English

结合使用shared_ptr和const引用

[英]Using shared_ptr with a const reference

I need to make several Worker classes that have a pointer to an Object owned by the main program. 我需要制作几个具有指向主程序所拥有的Object的指针的Worker类。 This is in C++14 这是在C ++ 14中

For reasons, the Object has to meet certain criteria - it has to have a deleted default constructor, its non-copyable, non-movable. 出于某种原因, Object必须满足某些条件-它必须具有已删除的默认构造函数,它的不可复制,不可移动。 And I need to use smart pointers. 而且我需要使用智能指针。

The main program will own the Object . 主程序将拥有Object Each worker class needs to read stuff from it 每个工人阶级都需要从中学到东西

class Object
{
  Object() = delete;
  ~Object();

  // Non copyable
  Object(const Object &other) = delete;
  Object &operator=(const Object &other) = delete;

  // Non movable
  Object(Object &&other) = delete;
  Object &operator=(Object &&other) = delete;

  // Constructor
  explicit Object(double threshold);
};

class Worker
{
public:
  void initialize(const Object& obj)
  {
    // Option 1 - errors out, complains its non copyable
    object_ptr = std::make_shared<const Object>(obj);

    // Option 2
    object_ptr = std::shared_ptr<const Object>(&obj);

    // Option 3
    object_ptr = std::shared_ptr<const Object>(&obj, [](const Object*){});
  }

  void doSomething();

private:
  std::shared_ptr<const Object> object_ptr;
};

int main () 
{
  Object object;

  Worker worker1;
  Worker worker2;

  worker1.initialize(object);
  worker2.initialize(object);

  while(1)
  {
    // Main does stuff to Object

    worker1.doSomething();
    worker2.doSomething();
  }

  return 0;
}

What's the best way to initialize the pointer inside of Worker ? 初始化Worker内部指针的最佳方法是什么?

I personally would do this 我个人会这样做

class Worker
{
public:
    void initialize(const Object& obj)
    {
        object_ptr = &obj;
    }
private:
    const Object* object_ptr = nullptr;
};

A raw pointer indicates non-ownership, which is exactly what the situation is. 原始指针指示非所有权,这正是实际情况。

If you must use a shared_ptr , there is no way around passing in one as an argument, shared_ptr has more data associated with it than just the managed object. 如果必须使用shared_ptr ,则没有办法传入一个作为参数, shared_ptr与其关联的数据要多于托管对象。

class Worker
{
public:
    void initialize(std::shared_ptr<const Object> p)
    {
        swap(object_ptr, p);
    }
private:
    std::shared_ptr<const Object> object_ptr;
};

int main()
{
    auto obj = std::make_shared<const Object>();
    //...
}

A shared_ptr means exactly what it says: the resource is shared . shared_ptr确切含义是:资源是shared To pass around a shared_ptr is to proclaim there are multiple owners and the resource is common to all of them, aka the resource must outlive any of them. 要传递shared_ptr就是要声明有多个所有者,并且资源是所有所有者共有的资源,也就是说,该资源必须比其中任何一个都寿命更长。

Note how you have the object on the stack (or rather, have automatic storage duration) which is indicative that this resource is not in fact, owned by the workers. 请注意您如何在堆栈上放置对象(或者具有自动存储期限),这表明该资源实际上不是由工作人员拥有的。 By definition of the workers, we know automatically that the object will outlive the workers, and this is by far superior to using shared_ptr s. 根据工作程序的定义,我们自动知道该对象将超出工作程序的寿命,这远远优于使用shared_ptr

Why not use shared_ptr's aliasing constructor . 为什么不使用shared_ptr的别名构造函数

template< class Y > 
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept; 

This allows you to create a shared_ptr, but not actually own the object, so the stored value is not actually reference counted. 这使您可以创建一个shared_ptr,但实际上并不拥有该对象,因此,存储的值实际上并未进行引用计数。 This means the referenced object must remain valid externally. 这意味着引用的对象必须在外部保持有效。

In this case, just set initialize to be: 在这种情况下,只需将初始化设置为:

void initialize(const Object& obj)
  {
    typedef std::shared_ptr<const Object> my_ptr;
    object_ptr = my_ptr(my_ptr(), &obj);
  }

It's a hack, and it will fake a true shared_ptr, but it will work. 这是一个hack,它会伪造一个真正的shared_ptr,但是可以工作。 For a self-contained, external example, try: 对于一个独立的外部示例,请尝试:

#include <memory>

struct x_t
{
    x_t() = delete;
    x_t(const x_t&) = delete;
    x_t(x_t&&) = delete;
    x_t(double y) {}
};

int main()
{
    typedef std::shared_ptr<const x_t> x_t_ptr;
    const x_t x(5);

    x_t_ptr ptr = x_t_ptr(x_t_ptr(), &x);

    return 0;
}

I should really warn you that you should not do this, since you will appear to have memory safety when you have no such thing. 我真的应该警告您,不要这样做,因为当您没有这种东西时,您似乎将具有内存安全性。 Basically, you're making a guarantee that you have memory safety, while then effectively using a raw pointer to a temporary object. 基本上,您要确保自己具有内存安全性,然后有效地使用指向临时对象的原始指针。 This is very dangerous. 这是非常危险的。

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

相关问题 将对具有shared_ptr作为值的映射的引用转换为对具有shared_ptr和const作为值的映射的引用 - Convert reference to map having shared_ptr as value to reference to map having shared_ptr to const as value 做boost :: shared_ptr <T> 和boost :: shared_ptr <const T> 分享参考计数? - Do boost::shared_ptr<T> and boost::shared_ptr<const T> share the reference count? 对shared_ptr中的const int的未定义引用 - undefined reference to const int within shared_ptr 我应该使用const引用还是boost :: shared_ptr? - Should I use a const reference or a boost::shared_ptr? std::move(const shared_ptr reference) 是什么意思? - what does std::move(const shared_ptr reference) mean? 为什么const shared_ptr <const T>&和const shared_ptr <T>&显示不同的引用计数? - Why do const shared_ptr<const T>& and const shared_ptr<T>& show different reference counts? 使用shared_ptr <const T> 从存储的shared_ptr <T> - Using a shared_ptr<const T> from a stored shared_ptr<T> 将shared_ptr的向量转换为shared_ptr的向量为const - Turning vector of shared_ptr into vector of shared_ptr to const 使用Boost Python与shared_ptr <const T> - Using Boost Python with shared_ptr<const T> 正在使用 std::vector&lt; std::shared_ptr<const T> &gt; 反模式? - Is using std::vector< std::shared_ptr<const T> > an antipattern?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM