gpt4 book ai didi

c++ - 使用 unique_ptr 数据成员重载用户定义类型的 operator=

转载 作者:行者123 更新时间:2023-11-30 04:55:33 28 4
gpt4 key购买 nike

我有一个用户定义的类,它有一个 std::unique_ptr 成员。我正在尝试重载赋值运算符以将相同类型的对象新建到 unique_ptr 成员或将值分配给 ptr 值。

class object
{
public:
// POD types

object& operator=(const object& _obj);

std::unique_ptr<baseClass> ptr;
}

我试过使用:

std::unique_ptr::swap()

但是交换函数是非常量的,所以我尝试分配结果:

std::unique_ptr::get()

ptr 然后调用:

std::unique_ptr::release()

但 release 也是非 const,所以我不能保证 ptr 会被正确销毁,因为旧的 ptr 仍然拥有所有权。 las,unique_ptroperator=() 不接受对另一个 unique_ptr 的非常量引用,所以我选择将 operator= 作为所以对于我的类(class)。

object& object::operator=(const object& _obj)
{
//POD types use operator= as normal
ptr.reset(nullptr);

return *this;
}

稍后只需调用 setPtr() 方法来设置 ptr。我只想检测类型并使用以下方法分配 ptr:

ptr.reset(new detectedType );

但整个 Stack Overflow 和我首选的搜索引擎的共识是,检测这样的类型将是一个设计缺陷。我的问题是:我是否忽略了一些简单的事情,是否有更好的方法为具有 unique_ptr 成员的用户定义类型重载赋值运算符?

后期编辑前: 我将参数更改为 object& 而不是 const object& 并且它起作用了。这是纠正此问题的好方法,还是我应该尝试仅使用对其他类的 const 引用?

最佳答案

My question is: am I overlooking something simple and is there a better way to overload the assignment operator for user defined types that have a unique_ptr member?

确实有。这分解为了解 C++ 中的智能指针的作用。通常你使用 std::unique_ptr 如果你的对象只有一个引用。这就是为什么 std_unique_ptr 既不可复制构造也不可复制赋值的原因。如果您使用 ptr.get() 手动创建 std::unique_ptr 的两个拷贝,您将最终处于无效状态,因为一旦一个拷贝离开范围,std::unique_ptr 析构函数也将破坏它指向的对象,使另一个 std::unqiue_ptr 处于无效状态(它指向到释放的内存位置)。因此,如果可能有多个对您的对象的引用,您应该改用 std::shared_ptr

在您的示例中,问题是您想要实现什么?

如果您希望您的赋值运算符在调用 a = b 之后,a.ptrb.ptr 指向完全相同的对象对象(即存储相同的指针)使用共享指针。在这种情况下,您绝对不应该使用唯一指针,因为为 ab 调用析构函数会破坏指向的对象,留下 ab 处于无效状态。

如果您希望在调用 a = b 之后,a.ptr 指向 *(b.ptr) 的独立拷贝,您可以确实使用一个唯一的指针并像这样实现你的赋值运算符(前提是 baseClass 是可复制解释的):

object& object::operator=(const object& _obj)
{
//POD types use operator= as normal
ptr.reset(new baseClass(*_obj.ptr));

return *this;
}

但是请注意,这仅在 baseClassfinal 时有效(不太可能考虑名称...),即 ptr 不会存储指向派生类对象的指针。否则这会导致 slicing正如 BenVoigt 所指出的。

最后,通常期望调用 a = b 不会更改 b。因此,使 ptr 成员可变并使用 swap 对我来说听起来不是个好主意。如果出于性能(或其他)考虑而想要实现此行为,我建议改为实现移动赋值运算符

object& object::operator=(object&& _obj)
{
//POD types use operator= as normal
ptr = std::move(_obj.ptr);

return *this;
}

并调用 a = std::move(b),这表明 b 可能最终处于不同的状态。

关于c++ - 使用 unique_ptr 数据成员重载用户定义类型的 operator=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52960477/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com