繁体   English   中英

从派生类构造函数调用基类构造函数

[英]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。 编译器如何区分这两者。

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

有一条旧的规则,继承自C,它尽力驱动程序员疯狂:

如果它可以是声明,则将其视为声明。

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

baseClass(ID);

被视为

baseClass ID;  

(在这个阶段没有检查“ID”是否已经意味着什么,这只是语法。)
在稍后阶段,当参数“ID”已知时,这将成为重新定义。

另一方面,

baseClass 10; 

不可能是一个宣言,所以它意味着

 baseClass(10);

它构造一个未命名的baseClass实例并立即抛出它。

线的解释

baseClass(ID);

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

6.8模糊度解析

1语法中涉及表达式语句和声明存在歧义:具有函数式显式类型转换(5.2.3)的表达式语句 ,因为其最左侧的子表达式与第一个声明符以a开头的声明无法区分( 在这些情况下,声明是声明。 [注意:为了消除歧义,可能必须检查整个声明以确定它是表达式声明还是声明。这消除了许多示例的歧义。

编译器不会识别你调用衍生物,他只是试图创建参数,而对于ID,他试图创建一个名为ID的变量,而对于10,他只是创建一个无名的临时对象。

情况1 :-

baseClass(ID);

这会给你错误,因为它被编译器解释为

baseClass ID; <<< You're redefining ID.

CASE_2: -

baseClass(10);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM