Subclass 成员变量作为初始化列表中 main-class 构造函数的参数 = 崩溃?

Subclass member variable as argument for main-class constructor in initialization list = 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:当然,我知道我可以用“"dog"”替换"testrace",但为了更容易转移到其他子classes,我更愿意一个让我为 Attributes() 使用可变参数的解决方案,我可以根据调用主 class.

的 subclass 而变化

首先当你有

...
string testrace = "dog";
Dalmatian (): Attributes{testrace}
... 

testrace 将隐藏全局 testrace,因为 class 成员在 class 范围内时会取代全局变量。这意味着示例二和示例三使用相同的变量,即 class 成员变量。

第二个和第三个崩溃的原因是因为您正在尝试使用一个以前没有构造过的变量。当你到达

Dalmatian (): Attributes{testrace}

testrace尚未构建。即使您在 class 主体中有 string testrace = "dog";,初始化也不会在调用 Attributes{testrace} 之后发生。所以 Attributes (string race) 得到一个未初始化的字符串,使用它是未定义的行为,也会导致你的崩溃。

问题是在构造 Attributes 时,testrace 变量尚未初始化,访问它会出现未定义的行为。

你可以简单地通过写

来解决这个问题
    Dalmatian (): Attributes{"dog"} { //using it as argument
        cout << "do i even arrive here" << endl;
    }

查看工作代码here