C ++。继承和初始化成员变量有编译错误

时间:2014-12-28 16:43:59

标签: c++ inheritance initialization initializer-list

我正在学习c ++继承,并对初始化成员变量有疑问。

对于这个问题,我写了两个示例代码。 (下)

代码1。编译成功

#include <iostream>

class SuperClass{
private:
    int var;
public:
    SuperClass() : var(0) {}
    SuperClass(int arg) : var(arg) {}
    int getVar(){
        return var;
    }
};

class SubClass : public SuperClass{
private:
    int subVar;
public:
    SubClass() : SuperClass(1),subVar(1) {}
    SubClass(int superArg, int subArg) : SuperClass(superArg), subVar(subArg) {}
    void print(){
        std::cout<<getVar()<<" & "<<subVar<<std::endl;
    }
};

int main(){
    SubClass object(3,2);
    object.print();

    return 0;
}

代码2。编译错误

#include <iostream>

class SuperClass{
private:
    int var;
public:
    SuperClass() : var(0) {}
    SuperClass(int arg) : var(arg) {}
    int getVar(){
        return var;
    }
};

class SubClass : public SuperClass{
private:
    int subVar;
public:
    SubClass() : SuperClass(1),subVar(1) {}
    SubClass(int superArg, int subArg) : subVar(subArg) {
        SuperClass(superArg);
    }
    void print(){
        std::cout<<getVar()<<" & "<<subVar<<std::endl;
    }
};

int main(){
    SubClass object(3,2);
    object.print();

    return 0;
}

上面的两个代码在调用SuperClass的构造函数(SuperClass(arg))时有所不同。

  • &#39;代码1&#39;以初始化列表的方式调用SuperClass构造函数。
  • &#39;代码2&#39;在SubClass的构造函数体中调用SuperClass构造函数。

我认为代码1&amp; 2将成功编译,但代码2编译错误。

(错误行号为20)

我不知道Code 2出现编译错误的原因。

在我的Xcode中,

编译错误消息重新定义&#39; superArg&#39;不同类型:&#39; SuperClass&#39; vs&#39; int&#39;

这条消息是什么意思,并且有任何我不知道的C ++语法?

(我的问题是为什么在SubClass的构造函数体中调用SuperClass的构造函数是错误的)

3 个答案:

答案 0 :(得分:1)

SubClass(int superArg, int subArg) : subVar(subArg) {
    SuperClass(superArg);
}

编译器将SuperClass(superArg);视为声明
(相当于SuperClass superArg;),
(而我期望创建一个临时的SuperClass)。

所以superArg intSuperClass一起宣布void foo(int arg) { double (arg); } 一次。

公开问题的最小代码:

{{1}}

答案 1 :(得分:0)

您收到错误是因为您尝试使用同名作为参数声明类型为SuperClass的局部变量。虽然看起来就像你在调用基类构造函数一样,但事实并非如此。构造函数不能在初始化列表之外直接调用,它们是未命名的特殊成员函数。

括号有效,用于避免Most Vexing Parse问题。这会导致像SuperClass x();这样的decalrations被解释为名为x的函数,它返回类型为SuperClass的值。括号的使用允许编译器推断它应该是变量。

如果您的目的是调用基类构造函数,则需要在初始化列表中执行此操作。

SubClass(int superArg, int subArg) : SuperClass(superArg), subVar(subArg)
{
}

如果您打算创建SuperClass类型的本地变量,则需要选择其他名称。

SubClass(int superArg, int subArg) : subVar(subArg)
{
    SuperClass superArgX;
}

答案 2 :(得分:-1)

你错了你的花括号。试试这个:

class SubClass : public SuperClass{
private:
    int subVar;
public:
    SubClass() : SuperClass(1),subVar(1) {}
    SubClass(int superArg, int subArg) : subVar(subArg), // { removed, comma added
        SuperClass(superArg) // semicolon removed
    {} // change curly braces like this
    void print(){
        std::cout<<getVar()<<" & "<<subVar<<std::endl;
    }
};