【问题标题】:copy constructor and assignment operator overloading for circular dependency classes循环依赖类的复制构造函数和赋值运算符重载
【发布时间】:2018-02-26 23:04:43
【问题描述】:

我在我的代码中使用了一些供应商库。一些代码如下所示。我看到它在类之间使用循环依赖。我无法理解将复制构造函数和赋值设为私有的原因是什么。 静态代码分析工具之一将违规抛出为“避免使用'new'来分配实例但不定义复制构造函数的类”。

class Parent;

class Child{
public:
Child(Parent& parent):mrParent(parent);

private:
Parent& mrParent;
};

class Parent{
public:
Parent();
~Parent();
//other declarations
Child* child;
private:
//copy and assignment are not allowed. Explicitly declaring private
Parent(const Parent&)
Parent& operator=(const Parent&);
};

【问题讨论】:

  • 原因在评论中://copy and assignment are not allowed. Explicitly declaring private
  • 另外,不要在规则检查工具中检查您无法更改的供应商库。
  • 我认为这个静态代码分析工具会发出错误的诊断信息。如果类具有默认的复制构造函数和/或赋值,则报告的问题将是相关的。基本上,看起来该工具没有识别出这些构造函数不能使用,因此不会出现问题。除非明确要求类实例是可复制的,否则复制构造函数和赋值应该是私有的/删除的。
  • 知道 OP 使用的是哪种静态分析工具会很有趣。

标签: c++ class oop


【解决方案1】:

您所拥有的是一种避免复制构造和分配给类的常用方法。
正如评论中所述,这就是编写该代码的人的意图:

//copy and assignment are not allowed. Explicitly declaring private

由于复制构造函数和赋值运算符都声明了但没有实现,这可能会导致静态分析工具发出警告。

在 C++11 中,拒绝复制构造和赋值的更好方法是:

Parent(const Parent&) = delete;
Parent& operator=(const Parent&) = delete;

这也应该避免来自静态分析工具的警告(如果没有,该工具可能已损坏)。

【讨论】:

  • 感谢您的解释。我试图了解避免复制构造函数和赋值的需要。我根据评论理解,但我不确定原因。同样关于 c++11 ,“= delete”在这里我得到编译错误作为纯函数定义的错误语法。是不是我的编译器不支持 C++11?
  • C++11:取决于你使用的编译器,如果它是一个相当新的 MSVC,它支持它,如果它是 GCC,你可能需要“强制”它使用 c++11(命令行选项 --std=c++11)
【解决方案2】:

从静态分析收到的警告是误报:复制构造函数不是“未定义”而是被明确拒绝。

如果复制构造函数真的“未定义”,那么编译器将生成一个不会按预期工作的构造函数(因为 new 运算符)。

但是,由于复制构造函数已被显式拒绝,因此编译器不会自行生成任何默认的复制构造函数。

【讨论】:

  • 它只是被声明,没有被定义(至少在这个sn-p中)。即使它被定义了,我认为你在字面上学究式地接受警告(尽管它可以更精确);它似乎意味着“避免使用'new'来分配实例但不定义复制构造函数的类[可以在任何可能创建此类的新实例的地方访问]”。为什么会有这个警告是另一回事。
【解决方案3】:

我无法理解将复制构造函数和赋值设为私有的原因是什么。

开发人员不希望该类的用户能够复制或/和分配该类的实例。

因此,它们不提供该功能,这可以通过在私有范围内声明它们来完成。

代码中的注释相当贬义:

//copy and assignment are not allowed. Explicitly declaring private

【讨论】:

    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多