从派生 class 构造函数调用基础 class 构造函数

Calling base class constructor from derived class constructor

问题代码如下:

#include<iostream>
using namespace std;

class baseClass
{
public:
    int objID;

    baseClass()
    {
        cout << "(1) Default constructor" << objID << endl;
    }

    baseClass(int ID)  // constructor
    {
        objID = ID;
        cout << "(2) Constructing base object with ID: " << objID << endl;
    }
};

class derivedClass : public baseClass
{
public:
    derivedClass(int ID)
    {
        baseClass(10);    // Line 1
        //baseClass(ID);  // Line 2
        cout << "(4) Constructing derived object with ID: " << objID << endl;
    }
};


int main(int argc, char** argv)
{
    derivedClass dcObj(1);

    return 0;
}

我遇到的问题是 derivedClass 构造函数中的第 2 行。它给了我重新定义形式参数的错误。我知道这是因为编译器认为我正在声明一个名为 "ID" 的 baseClass 类型的变量。而且我知道我应该在初始化列表中调用它。

但我的问题是为什么第 1 行可以正常工作?编译器将第 1 行解释为值为 10 的 baseClass 对象的实例化。那么为什么第 2 行不起作用。在这两种情况下我都传递了一个 int。编译器如何区分这两者。

编译器无法识别你调用导数, 他只是试图制作参数,对于 ID 他试图制作一个名为 ID 的变量,而对于 10 他只是制作一个无名的临时对象。

CASE_1 :-

baseClass(ID);

编译器将其解释为

,这会给您带来错误
baseClass ID; <<< You're redefining ID.

CASE_2 :-

baseClass(10);

由于 baseClass 10 解释是无意义的,编译器将其视为构造函数调用。

第 1 行有效,因为 baseClass 有一个默认构造函数 baseClass(),它会在您创建 derivedClass 的实例时自动调用。您在第 1 行中对 baseClass(10) 的调用创建了一个 类型为 baseClass 的临时对象 ,它从未被使用过。选择此调用是因为 10 不是有效的变量名,因此它被解释为函数的参数。

有一条从 C 继承而来的老规矩,它竭尽全力让程序员发疯:

if it can be a declaration, treat it as a declaration.

再加上 C++ 允许您在许多地方插入多余的括号这一事实 - int (x); 是一个有效的变量声明 - 这意味着

baseClass(ID);

被视为

baseClass ID;  

(在这个阶段没有检查 "ID" 是否已经意味着什么,这只是语法。)
在后期,当参数"ID"已知时,这就变成了重新定义。

另一方面,

baseClass 10; 

不可能是声明,所以理解为

 baseClass(10);

构造一个未命名的 baseClass 实例并立即将其丢弃。

行的解释

baseClass(ID);

作为声明可以追溯到标准。来自 C++ 草案标准 N3337(强调我的):

6.8 Ambiguity resolution

1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates many examples.