我需要创建几个Worker
类,这些类具有指向主程序所拥有的Object
的指针。这是在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
内初始化指针的最佳方法是什么?
答案 0 :(得分: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>();
//...
}
shared_ptr
表示其内容:资源共享。传递shared_ptr
是为了宣称有多个所有者,并且资源对所有人都是通用的,也就是说资源必须比任何资源都长。
请注意您如何在堆栈上使用 (或者更确切地说,具有自动存储持续时间),这表明此资源实际上并非由工作人员拥有。根据工人的定义,我们自动知道该对象将比工人更长,这远远优于使用shared_ptr
。
答案 1 :(得分:-2)
为什么不使用shared_ptr的aliasing constructor。
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
这允许您创建shared_ptr,但实际上并不拥有该对象,因此存储的值实际上不是引用计数。这意味着引用的对象必须在外部保持有效。
在这种情况下,只需将initialize设置为:
void initialize(const Object& obj)
{
typedef std::shared_ptr<const Object> my_ptr;
object_ptr = my_ptr(my_ptr(), &obj);
}
这是一个黑客攻击,它会伪造一个真正的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;
}
我应该警告你,你不应该这样做,因为当你没有这样的东西时,你似乎有记忆安全。基本上,您可以保证您具有内存安全性,同时有效地使用指向临时对象的原始指针。这非常危险。