子类成员变量作为初始化列表中的主类构造函数的参数= crash?

时间:2017-07-20 15:55:56

标签: c++ inheritance initialization-list

编程非常新,所以请原谅我可能没有看到明显的东西。

基本上我只是想知道为什么所有三个代码都会编译,但是在TWO和THREE的情况下生成的可执行文件CRASH (我用评论标记了差异)

ONE - 编译

#include <iostream>
#include <string>
using namespace std;

string testrace = "dog"; //defining it only globally

class Attributes {
    public:
    Attributes (string race){
        if (race == "human"){
            intelligence = 10;}
        else if (race == "dog"){
            intelligence = 4;}
    }
    int intelligence;
};

class Dalmatian: public Attributes{
    public:
        // but NOT locally
        Dalmatian (): Attributes{testrace} { //using it as an argument
            cout << "do i even arrive here" << endl;
        }
};

int main() {
    Dalmatian bob;
    cout << bob.intelligence << endl;
}

两次崩溃

#include <iostream>
#include <string>
using namespace std;


class Attributes {
    public:
    Attributes (string race){
        if (race == "human"){
            intelligence = 10;}
        else if (race == "dog"){
            intelligence = 4;}
    }
    int intelligence;
};

class Dalmatian: public Attributes{
    public:
        string testrace = "dog"; //only defining it locally
        Dalmatian (): Attributes{testrace} { //using it as argument
            cout << "do i even arrive here" << endl;
        }
};

int main() {
    Dalmatian bob;
    cout << bob.intelligence << endl;
}

三次 - 崩溃

#include <iostream>
#include <string>
using namespace std;

string testrace = "dog"; //defining it globally

class Attributes {
    public:
    Attributes (string race){
        if (race == "human"){
            intelligence = 10;}
        else if (race == "dog"){
            intelligence = 4;}
    }
    int intelligence;
};

class Dalmatian: public Attributes{
    public:
        string testrace = "dog"; // AND locally
        Dalmatian (): Attributes{testrace} { //using it as argument
            cout << "do i even arrive here" << endl;
        }
};

int main() {
    Dalmatian bob;
    cout << bob.intelligence << endl;
}

当然,我正在寻找的是两个例子的替代品。 但是我也有兴趣解释为什么所有这三段代码都能正常编译,但是由2和3引起的可执行文件会崩溃。

编辑:我知道示例一和三不合理,我将它们用于示范目的。 (还修正了我的措辞,编译器做得很好,可执行文件崩溃了);

EDIT2:我当然知道我可以直接替换&#34; testrace&#34;与&#34;&#34; dog&#34;&#34;,但为了更容易转移到其他子类,我更喜欢一个允许我使用Attributes()的变量参数的解决方案,我可以根据子类,即调用主类。

2 个答案:

答案 0 :(得分:5)

当你有

时首先关闭
...
string testrace = "dog";
Dalmatian (): Attributes{testrace}
... 
当您在类范围内时,

testrace将隐藏全局testrace,因为类成员会取代全局变量。这意味着示例二和三都使用相同的变量,类成员变量。

因为你试图使用之前没有构造过的变量,因此第二和第三次崩溃的原因。当你到达

Dalmatian (): Attributes{testrace}

testrace尚未构建。即使在类体中有string testrace = "dog";,在调用Attributes{testrace}之前初始化也不会发生。因此Attributes (string race)获取未初始化的字符串并使用它是未定义的行为并且还会导致崩溃。

答案 1 :(得分:0)

问题是,在构造null时,Attributes变量尚未初始化,并且访问它会给您带来未定义的行为。

您可以通过编写

来解决此问题
testrace

查看工作代码here