需要一个示例来说明默认构造函数是不会被继承的。

6

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

下面有一个示例:

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

struct D2 : B2 {
  using B2::B2;
};

非常好的解释:

The candidate set of inherited constructors in D2 for B2 is

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

最重要的是:

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

对我来说,这个例子并没有展示出不同之处,因为即使这个构造函数被继承了,它的行为也不会与隐式声明的默认构造函数不同。

我需要一个例子,能够展示出区别,并且对于熟悉 C++03 但想学习 C++11 的观众来说易于理解。


[更新]
所有答案(包括我的)都是 "如果默认构造函数被继承,则示例将编译/不编译" 这种类型的。

我更喜欢答案中的结果(可观察行为)与否有所不同。

3个回答

3

可能的一个区别是:从具有默认构造函数的类进行多个构造函数继承。例如:

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 中都继承一个,默认构造函数会产生二义性。
我想不出多重构造函数继承的用例,所以这可能不是你要找的完美例子,但这是一些内容。

2

请考虑以下内容:

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) 构造函数。


从提案(例如N2203)来看,这似乎是不继承复制/移动和默认构造函数的原因之一。 - dyp

1

以下是继承构造函数的特性所产生的示例:

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接