c++ 为什么继承的构造函数不应该继承默认参数?

C引物(第5版)第629页说明:

  • If a base class constructor has default arguments, those arguments are not inherited. Instead, the derived class gets multiple inherited constructors in which each parameter with a default argument is successively omitted.

这个规则背后的原因是什么?

最佳答案
给定目前的措辞;我认为这些条款是规定的(C++ WD n4527第12.9 / 1号),原因很少(但主要是避免潜在的模糊);

>避免歧义.即如果您开始为自己的构造函数提供匹配参数,那么这将允许这些构造函数与继承的构造函数不冲突(不明确)
>保持其效果.即客户端代码将是什么样的

inheriting constructors是一种类似于代码生成的技术(“我想要我的基础”).没有办法指定你正在获取哪些构造函数,所以你基本上得到它们,所以编译器很注意不会产生不明确的构造函数.

作为例子;

#include <iostream>
using namespace std;
struct Base {
    Base (int a = 0, int b = 1) { cout << "Base" << a << b << endl; }
};
struct Derived : Base {
    // This would be ambiguous if the inherited constructor was Derived(int=0,int=1)
    Derived(int c) { cout << "Derived" << c << endl; }
    using Base::Base;
};
int main()
{
    Derived d1(3);
    Derived d2(4,5);
}

输出;

Base01
Derived3
Base45

Sample code.

n4429(Jonathan Wakely指出)提出了关于继承构造函数和类的使用声明的措辞的改进.

鉴于提案的意图;

… this proposal makes inheriting a constructor act just like inheriting any other base class member, to the extent possible.

有以下变化(新措辞);

Change in 7.3.3 namespace.udecl paragraph 15:

When a using-declaration brings declarations from a base class into a derived class… Such hidden or overridden declarations are excluded from the set of declarations introduced by the using-declaration.

并且立即遵循一个直接涉及构造函数的示例(尽管没有默认参数);

struct B1 {
  B1(int);
};

struct B2 {
  B2(int);
};

struct D1 : B1, B2 {
  using B1::B1;
  using B2::B2;
};
D1 d1(0);    // ill-formed: ambiguous

struct D2 : B1, B2 {
  using B1::B1;
  using B2::B2;
  D2(int);   // OK: D2::D2(int) hides B1::B1(int) and B2::B2(int)
};
D2 d2(0);    // calls D2::D2(int)

简而言之,虽然可能不是最终的措辞,但似乎意图是允许构造函数与默认参数一起使用,并明确排除隐藏和覆盖的声明,因此我相信应该考虑任何歧义.措辞似乎简化了标准,但产生了相同的结果w.r.t.它被用于客户端代码.

转载注明原文:c++ 为什么继承的构造函数不应该继承默认参数? - 代码日志