C++ 使用带有常量引用的共享\u ptr

C++ 使用带有常量引用的共享\u ptr,c++,c++14,shared-ptr,C++,C++14,Shared Ptr,我需要创建几个Worker类,这些类的指针指向主程序拥有的对象。这是在C++14中实现的 出于某些原因,对象必须满足某些标准-它必须有一个已删除的默认构造函数,其不可复制、不可移动。我需要使用智能指针 主程序将拥有对象。每个工人阶级都需要阅读其中的内容 class Object { Object() = delete; ~Object(); // Non copyable Object(const Object &other) = delete; Object &a

我需要创建几个
Worker
类,这些类的指针指向主程序拥有的
对象。这是在C++14中实现的

出于某些原因,
对象必须满足某些标准-它必须有一个已删除的默认构造函数,其不可复制、不可移动。我需要使用智能指针

主程序将拥有
对象
。每个工人阶级都需要阅读其中的内容

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;
}
类对象
{
对象()=删除;
~Object();
//不可复制
对象(常量对象和其他)=删除;
对象和运算符=(常量对象和其他)=删除;
//不可移动
对象(对象和其他)=删除;
对象和运算符=(对象和其他)=删除;
//建造师
显式对象(双阈值);
};
班主任
{
公众:
无效初始化(常量对象和对象)
{
//选项1-出错,抱怨其不可复制
对象_ptr=std::使_共享(obj);
//选择2
object_ptr=std::shared_ptr(&obj);
//选择3
object_ptr=std::shared_ptr(&obj,[](const object*){});
}
无效剂量();
私人:
std::共享的\u ptr对象\u ptr;
};
int main()
{
对象对象;
工人1名;
工人2名;
worker1.初始化(对象);
worker2.初始化(对象);
而(1)
{
//Main对Object做了一些事情
工人1.剂量测定法();
工人2.剂量测定法();
}
返回0;
}
工作者
中初始化指针的最佳方法是什么

为什么不使用共享的ptr

模板
共享ptr(常量共享ptr&r,元素类型*ptr)无例外;
这允许您创建一个共享的_ptr,但不实际拥有该对象,因此存储的值实际上不被引用计数。这意味着引用的对象必须在外部保持有效

在这种情况下,只需将initialize设置为:

void initialize(const Object& obj)
  {
    typedef std::shared_ptr<const Object> my_ptr;
    object_ptr = my_ptr(my_ptr(), &obj);
  }
void初始化(常量对象和对象)
{
typedef std::shared_ptr my_ptr;
object_ptr=my_ptr(my_ptr(),&obj);
}
这是一个黑客,它将伪造一个真正的共享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;
}
#包括
结构x\u t
{
x_t()=删除;
x_t(const x_t&)=删除;
x_t(x_t&&)=删除;
x_t(双y){}
};
int main()
{
typedef std::共享_ptr x_t_ptr;
常数x_t x(5);
x_t_ptr ptr=x_t_ptr(x_t_ptr(),&x);
返回0;
}
我真的应该警告你,你不应该这样做,因为当你没有这样的东西时,你会看起来有记忆安全。基本上,您是在保证内存安全,同时有效地使用指向临时对象的原始指针。这是非常危险的。

为什么不使用共享的ptr

模板
共享ptr(常量共享ptr&r,元素类型*ptr)无例外;
这允许您创建一个共享的_ptr,但不实际拥有该对象,因此存储的值实际上不被引用计数。这意味着引用的对象必须在外部保持有效

在这种情况下,只需将initialize设置为:

void initialize(const Object& obj)
  {
    typedef std::shared_ptr<const Object> my_ptr;
    object_ptr = my_ptr(my_ptr(), &obj);
  }
void初始化(常量对象和对象)
{
typedef std::shared_ptr my_ptr;
object_ptr=my_ptr(my_ptr(),&obj);
}
这是一个黑客,它将伪造一个真正的共享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;
}
#包括
结构x\u t
{
x_t()=删除;
x_t(const x_t&)=删除;
x_t(x_t&&)=删除;
x_t(双y){}
};
int main()
{
typedef std::共享_ptr x_t_ptr;
常数x_t x(5);
x_t_ptr ptr=x_t_ptr(x_t_ptr(),&x);
返回0;
}

我真的应该警告你,你不应该这样做,因为当你没有这样的东西时,你会看起来有记忆安全。基本上,您是在保证内存安全,同时有效地使用指向临时对象的原始指针。这是非常危险的。

我个人会这样做

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>();
    //...
}
类工作者
{
公众:
无效初始化(标准::共享\u ptr p)
{
交换(对象_ptr,p);
}
私人:
std::共享的\u ptr对象\u ptr;
};
int main()
{
auto obj=std::make_shared();
//...
}
shared\u ptr
的意思就是:资源是共享的。传递一个
共享的\u ptr
就是宣布有多个所有者,并且资源对他们所有人来说都是公共的,也就是说,资源必须比他们中的任何一个都长寿


请注意,对象如何位于堆栈上(或者更确切地说,具有自动存储持续时间),这表明此资源实际上不属于工作人员。根据worker的定义,我们自动知道对象将比worker更长寿,这远远优于使用
shared\u ptr
s。

我个人会这样做

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>();
    //...
}
类工作者
{
公众:
无效初始化(标准::共享\u ptr p)
{
交换(对象_ptr,p);
}
私人:
std::共享的\u ptr对象\u ptr;
};
int main()
{
auto obj=std::make_shared();
//...
}
shared\u ptr
的意思就是:资源是共享的。传递一个
共享的\u ptr
就是宣布有多个所有者,并且资源对他们所有人来说都是公共的,也就是说,资源必须比他们中的任何一个都长寿

请注意对象是如何在堆栈上(或者更确切地说,具有自动存储持续时间)的