需要一个示例来显示默认构造函数不是继承的

Need an example showing that default constructor is not inherited

本文关键字:构造函数 默认 显示 继承 一个      更新时间:2023-10-16

我知道默认构造函数不是继承的,如n3337中所述。

这里有一个例子:

struct B2 {
  B2(int = 13, int = 42);
};
struct D2 : B2 {
  using B2::B2;
};

很好的解释:

B2D2中继承构造函数的候选集是

...
—B2(int = 13, int = 42)
—B2(int = 13)
—B2()

最重要的是:

D2中存在的构造函数集是
—D2(),隐式声明的默认构造函数,未继承

对我来说,这个例子并没有显示出区别,从某种意义上说,即使这个构造函数是继承的,它的行为也与隐式声明的默认构造函数没有什么不同。

我需要一个例子,用一种容易理解的方式来展示差异,比如说,对于熟悉C++03但想学习C++11的观众来说。


[更新]
所有的答案(包括我自己的答案)都是善意的"如果继承了默认的c-tor,则该示例将编译/不编译";。

我更喜欢结果(可观察的行为)与其他情况不同的答案。

一个可能的区别是:从具有默认构造函数的类继承多个构造函数。例如:
struct A { A(int=0); };
struct B { B(double=3.14); };
struct C : A, B {
  using A::A;
  using B::B;
};
C c;

如果继承了默认构造函数,C将从AB中继承一个,从而导致歧义。

我想不出多构造函数继承的用例,所以这可能不是你想要的完美例子,但它很重要。

考虑:

struct foo
{
    foo() {}
    foo(int) {}
};
struct bar : foo
{
    using foo::foo;
};
int main()
{
    bar b;
}

此编译:由于bar没有用户声明的构造函数,因此将隐式声明默认构造函数。

struct foo
{
    foo() {}
    foo(int) {}
};
struct bar : foo
{
    using foo::foo;
    bar(double) {}
};
int main()
{
    bar b;
}

这不会编译。默认构造函数不是继承的,也不是隐式声明的,因为有bar(double)构造函数。

下面是一个例子,它可以从继承构造函数的以下特性中生成:

12.9继承构造函数
[…]
4) 这样声明的构造函数与X.中的相应构造函数具有相同的访问权限

所以我的建议是在基础中有一个受保护的默认构造函数:

class Base {
protected:
    Base(int) {}
    Base() = default;
};

如果此构造函数是派生的,则派生类无法实例化,因为派生构造函数将具有受保护的访问权限。如果不是派生的,则默认隐式声明的构造函数具有公共访问权限:

struct Derived : Base {
    using Base::Base;
};
int main() {
    Derived d1{};  // not inherited, default constructor is public
    Derived d2{1}; // not compiling since this c-tor is inherited, thus protected
}