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

Trv*_*ack 1 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;
}
Run Code Online (Sandbox Code Playgroud)

两次 - 崩溃

#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;
}
Run Code Online (Sandbox Code Playgroud)

三 - 崩溃

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我知道示例ONE和THREE没有意义,我将它们用于演示目的.(还修复了我的措辞,编译器做得很好,可执行文件崩溃了);

EDIT2:我这样做,当然,意识到我可以只更换"testrace"与""狗"",但更容易转让给其他子类,我宁愿一个解决方案,让我使用的属性()变量参数,即我可以根据子类来调整,即调用主类.

Nat*_*ica 5

首先,当你有

...
string testrace = "dog";
Dalmatian (): Attributes{testrace}
... 
Run Code Online (Sandbox Code Playgroud)

testracetestrace当您在类范围内时,将隐藏全局作为类成员取代全局变量.这意味着示例二和三都使用相同的变量,即类成员变量.

之所以第二次和第三次崩溃是因为你试图使用之前没有构造过的变量.当你到达

Dalmatian (): Attributes{testrace}
Run Code Online (Sandbox Code Playgroud)

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