繁体   English   中英

结合使用shared_ptr和const引用

[英]Using shared_ptr with a const reference

我需要制作几个具有指向主程序所拥有的Object的指针的Worker类。 这是在C ++ 14中

出于某种原因, Object必须满足某些条件-它必须具有已删除的默认构造函数,它的不可复制,不可移动。 而且我需要使用智能指针。

主程序将拥有Object 每个工人阶级都需要从中学到东西

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;
}

初始化Worker内部指针的最佳方法是什么?

我个人会这样做

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

原始指针指示非所有权,这正是实际情况。

如果必须使用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>();
    //...
}

shared_ptr确切含义是:资源是shared 要传递shared_ptr就是要声明有多个所有者,并且资源是所有所有者共有的资源,也就是说,该资源必须比其中任何一个都寿命更长。

请注意您如何在堆栈上放置对象(或者具有自动存储期限),这表明该资源实际上不是由工作人员拥有的。 根据工作程序的定义,我们自动知道该对象将超出工作程序的寿命,这远远优于使用shared_ptr

为什么不使用shared_ptr的别名构造函数

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

这使您可以创建一个shared_ptr,但实际上并不拥有该对象,因此,存储的值实际上并未进行引用计数。 这意味着引用的对象必须在外部保持有效。

在这种情况下,只需将初始化设置为:

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

这是一个hack,它会伪造一个真正的shared_ptr,但是可以工作。 对于一个独立的外部示例,请尝试:

#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;
}

我真的应该警告您,不要这样做,因为当您没有这种东西时,您似乎将具有内存安全性。 基本上,您要确保自己具有内存安全性,然后有效地使用指向临时对象的原始指针。 这是非常危险的。

暂无
暂无

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

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