为什么这个C++程序即使没有构造类对象也能成功运行

Why could this C++ program run successfully even without constructing the class object?

本文关键字:对象 运行 成功 C++ 程序 为什么      更新时间:2023-10-16

为什么这个C++程序即使不构造类对象也能成功运行?让我们看看下面的代码:

#include<iostream>
using namespace std;
class Dopey
{
public:
Dopey() {cout << "Dopeyn";}
};
class Bashful
{
public:
Bashful() { cout << "BashFuln";}
void f() { cout << " f n";}
int i;
};
class Sneezy
{
public:
Sneezy(int i) {cout << "copy int n";}
Sneezy(Bashful d) { cout << "copy Bashfuln";}
Sneezy(Bashful* d) {d->f();d->i=100;} //How could this be correct without    
//  constructing d !!!!!!!!
Sneezy();
};
class Snow_White
{
public:
Snow_White();
Dopey dopey;
Sneezy sneezy;
Bashful bashful;
private:
int mumble;
};
Snow_White::Snow_White() : sneezy(&bashful)
{
mumble = 2048;
}
int main()
{
Snow_White s;
return 0;
}

该程序可以成功运行,具体如下:

Dopey
f
BashFul

请参阅,without constructing bashful,the f() could be invoked,为什么?并且当我将函数CCD_ 2改变为以下时:

Snow_White::Snow_White() : sneezy(bashful)
{
mumble = 2048;
}

它也是runs successfully without constructing bashful,cout如下:

Dopey
copy Bashful
Bashful

如有任何解释,我们将不胜感激!THX!

您的程序有未定义的行为,因为您在构造bashful之前就访问了它。

您的问题与初始化列表有关。害羞是在打喷嚏之后宣布的。因此,在此代码中:

Snow_White::Snow_White() : sneezy(&bashful)

bashul尚未构建,因为根据Snow_White的声明,sneezy必须首先构建(是的,顺序很重要)。因此,传入sneezy构造函数的参数指向一个统一的对象。在这一点上,它起作用的原因是chris所链接的。请记住,尽管它起作用,但根据C++标准,行为是未定义的,这意味着你不能也绝不能依赖它来工作

然而,真正的问题是,bashful还没有被构建出来。

要解决这个问题,您需要更改Snow_White类的声明,使bashful位于sneezy:之前

class Snow_White
{
public:
Snow_White();
Dopey dopey;
Bashful bashful;
Sneezy sneezy;
private:
int mumble;
};

避免这种情况发生的一种方法是始终保持声明和初始化列表按字母顺序排列。

另一种方法是从一开始就保持你的类较小,所以这从来都不是问题:)

构建bashful成员,如输出中包含bashful所示。的确,它不是在bashful的地址被获取并传递给其他成员的构造函数之前构造的。

成员初始化的顺序有特定的规则,但构造函数初始化列表中的初始化或使用顺序不是这些规则中的因素之一。