为什么不推荐“子类复制构造函数调用虚拟继承的父琐碎构造函数”

Why is "subclass copy constructor calling virtual inherited parent trivial constructor" not recommended

提问人:依奈ちゃん 提问时间:1/8/2022 最后编辑:依奈ちゃん 更新时间:1/9/2022 访问量:77

问:

我有一个类,它实际上继承自一个只有普通构造函数的基类,但复制构造函数被显式删除。现在我需要为这个子类提供一个复制构造函数,并调用基类的普通构造函数,如下所示:

class A {
protected:
    explicit A () {}
    A (A const&) = delete;
    virtual ~A () {}
};
class B : virtual public A {
protected:
    explicit B () {}
    B (B const&): A () {} 
    virtual ~B () {}
};
class C : public B {
public:
    explicit C () noexcept {}
    C (C const&) noexcept
      try: B () {} catch (...) { }
    ~C () noexcept {}
};
int main () {
    C c1;
    C c2{c1};
    return 0;
}

当我使用 godbolt.org ( https://godbolt.org/z/q6eWTj7vP ) 编译时没有警告。在“Dev C++ 5.11,TDM-GCC 4.9.2 64位版本”下,如果我只使用编译选项进行编译,则不会出现错误。但是,添加编译选项后,会生成警告(在类 C 中):-std=c++11-Wextra

17  5   C:\Users\test.cpp   [Warning] base class 'class A' should be explicitly initialized in the copy constructor [-Wextra]

当我在上面的代码中删除关键字“virtual”时,警告消失了。class B : public virtual A {

我不能忽略任何警告消息,所以我想知道为什么会生成此警告消息。谢谢。

C++ 复制构造函数 virtual-inheritance

评论

2赞 Peter 1/8/2022
出现此警告的原因是,在其他基的构造函数之前无条件地调用虚拟基的构造函数。在构造 时,会忽略 s 构造函数的初始化器列表中 s 构造函数的调用,并且您编写的复制构造函数隐式等价于 。该警告基于一种风格考虑,即您应该明确这一点。ABCCC (C const&) noexcept try: A(), B () { } catch (...) {}
0赞 依奈ちゃん 1/8/2022
非常感谢你,你是对的。我误解了警告的意思。
0赞 Davis Herring 1/9/2022
这些函数-try-块有什么用?当与构造函数一起使用时,它们无法抑制异常。
0赞 依奈ちゃん 1/9/2022
放在这里真的没用。由于原始继承系统的复杂性,中间有 noexcept (false) 构造函数。简化代码时忘了删除它。

答: 暂无答案