【问题标题】:Is it necessary to block the assignment operator and the copy constructor when using smart pointers?使用智能指针时是否需要阻塞赋值运算符和复制构造函数?
【发布时间】:2012-10-22 22:03:29
【问题描述】:

我在几个地方看到过这样的建议:要么定义你自己的赋值运算符/复制构造函数,要么通过将它们声明为私有来阻止默认值。

然而,我能找到的唯一危险是创建指针副本的问题,这些副本以后可能是悬空指针。

在现代 C++ 中指针很少见,大多数类只使用智能指针(例如来自 boost 或来自 C++11 中的 std 库)。对于没有原始指针的类,是否还需要声明赋值运算符和复制构造函数?

主要是:不这样做有什么危险?会发生什么样的意外行为?

【问题讨论】:

  • 您需要定义自己的赋值运算符或复制构造函数的唯一时间是在定义析构函数的同时。这是Rule of Three。但是,如果您只使用资源管理类而不创建一个,则不需要做任何特别的事情,因为为您的类隐式生成的特殊函数将使用资源管理类中专门编写的函数,这应该只是正确的事情。

标签: c++ operator-overloading smart-pointers copy-constructor


【解决方案1】:

这在问题What is The Rule of Three?中有解释

下面的网站也有很好的解释:

Can I trust the Compiler-Generated Copy Constructor and Assignment Operator?

编译器生成的代码是您最好的朋友,前提是 您坚持良好的 OO 风格实践并了解规则。如解释 在第一部分,编译器生成的复制构造函数和赋值 运算符执行用户声明的数据成员的成员方式复制。经过 替换低级数据类型——原始指针和字符数组 实例——与他们的高级标准库对应物 std::tr1::shared_ptr 和 std::string,您不仅要消除 与手动资源管理相关的繁重错误,你也是 保证编译器生成的复制构造函数和 赋值运算符会做正确的事情。

【讨论】:

    【解决方案2】:

    不定义自己的赋值运算符/复制/移动构造函数的危险在于可能出现意外行为。这些操作很容易在您不知情的情况下被调用,从而导致意外行为。在这种情况下,将它们声明为私有将导致编译错误。

    另请注意,并非所有地方都使用智能指针。有更多受限环境(例如内核、嵌入式等)通常没有 STL 或 boost。

    【讨论】:

    • 问题是:什么样的意外行为会对应用程序造成危险?
    • 任何意想不到的行为都可能是危险的,因为它是意想不到的......
    【解决方案3】:

    不是没有必要隐藏这些运算符。 std::unique_ptr 已经是不可复制的(你只能移动它)。和其他类型 - std::shared_ptr 将增加内部引用计数,std::weak_ptr 不会做任何事情,因为它有 lock 方法。你可以阅读更多here (Boost libs)

    【讨论】:

    • 增加内部引用计数不是您想要的应用程序所必需的,并且可能会产生逻辑后果
    • 您可以忘记及时重置这些指针以释放它们拥有的内存。
    猜你喜欢
    • 2023-04-01
    • 2018-10-31
    • 1970-01-01
    • 2014-09-14
    • 2017-06-24
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多