【问题标题】:Disabling default constructor for non-POD classes禁用非 POD 类的默认构造函数
【发布时间】:2010-11-24 00:52:11
【问题描述】:

据我了解,C++ 默认复制构造函数仅在类是 POD 类时才会按预期运行。

我想知道如果对象不是 POD,是否有解决方案可以防止程序员编写(隐式或不)使用默认复制构造函数的代码。

我知道您始终可以将您的副本和作业设为私有以解决此问题,但我想知道是否有自动解决方案。例如,如果您的代码生成默认的复制构造函数调用并且您的类不是 POD,编译器可能会生成警告?

这里的目标是检测我忘记将复制/分配私有或手动定义它们的情况。

你们也知道 cppcheck 是否可以做到这一点吗?

【问题讨论】:

  • "C++ 默认复制构造函数仅在类是 POD 类时按预期运行。" ——这是错误的。只要它的所有成员都正确复制,默认的复制构造函数应该没问题。例如,如果我的类有一个vector,它将使用默认的复制构造函数很好地复制,因为它会调用vector的复制构造函数,而vector又会调用它的每个字符串的复制构造函数。
  • 好点。那么这个问题可能没有简单的解决方案。编译器必须通过所有继承/组合图来查看是否所有成员都定义了复制构造函数,或者是 POD,我猜:/

标签: c++ visual-c++ constructor copy warnings


【解决方案1】:

在 C++0x 中,您可以显式阻止使用这样的特殊成员函数:

struct NonCopyable {
    NonCopyable & operator=(const NonCopyable&) = delete;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable() = default;
};

请参阅here 了解更多详情。不幸的是,仍然是手动的,但比现在更优雅。

【讨论】:

    【解决方案2】:

    禁用默认构造的集中方法是使默认构造函数不可访问。

    您写道:“我想知道如果对象不是 POD,是否有防止程序员编写代码(无论是否隐含)使用默认复制构造函数的解决方案。”

    大概您的意思是您希望编译器对任何非 POD 对象的任何默认构造作出反应。

    抱歉,没有独立于编译器的方式。

    原因:很多非 POD 类,如智能指针和容器,如 std::vector,依赖于默认构造才能发挥作用。

    g++ 编译器有一个选项 -Weffc++ 来警告违反 Scott Meyers 的 Effective C++ 中的准则,但据我所知——我可能是错的——这不包括你的案子。不过据说可能很有用。

    干杯,

    【讨论】:

    • “抱歉,没有独立于编译器的方式”:是否有依赖于编译器的方式?我正在使用 Visual Studio 2008。
    • 实际上经过一些研究,-Weffc++ 或多或少地做了我想要的(派对但那是我的主要用例)来自 g++ 手册页:警告违反 Scott Meyers 的以下样式指南有效C++ 书籍:第 11 项:为具有动态分配内存的类定义复制构造函数和赋值运算符。
    【解决方案3】:

    不,因为这是语言的要求。

    【讨论】:

      【解决方案4】:

      创建类时,您有 3 种可能性:拥有默认复制 ctor、编写您自己的或禁用它(使用不同的方法;从 boost::noncopyable 继承以提及其中之一)。不清楚为什么编译器会警告您选择其中之一。

      【讨论】:

        猜你喜欢
        • 2010-10-30
        • 2015-10-20
        • 1970-01-01
        • 2019-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多