在下面的示例程序中,
为什么用户定义的型别别的静态和自动变量的输出不同?
/* test.cpp */
/* SalesData Class */
class SalesData {
public:
SalesData() = default;
// other member funcations
private:
std::string bookNo;
unsigned int unitsSold;
double revenue;
};
/*
* Prints the SalesData object
*/
std::ostream& print(std::ostream &os, const SalesData &item) {
os << "ISBN :\'" << item.isbn() << "\', Units Sold :" << item.unitsSold
<< ", Revenue :" << item.revenue << ", Avg. Price :"
<< item.avgPrice() << std::endl;
return os;
}
int main(int argc, char *argv[]) {
SalesData s;
static SalesData s2;
print(cout, s);
print(cout, s2);
return 0;
}
程序的输出是这样的——
$ ./test
ISBN :'', Units Sold :3417894856, Revenue :4.66042e-310, Avg. Price :1.36352e-319
ISBN :'', Units Sold :0, Revenue :0, Avg. Price :0
静态如何改变合成默认建构式中的场景?
uj5u.com热心网友回复:
s
默认建构式在和上具有相同的行为s2
。不同之处在于,对于静态区域变量,
关于零初始化:
这意味着s2
将首先进行零初始化,因为它的资料成员也被零初始化;然后main()
通过默认建构式输入它是默认初始化的。
uj5u.com热心网友回复:
案例一
让我们考虑一下SalesData s;
。
在这种情况下,SalesData
具有名称的型别物件s
是使用 的默认建构式构造的SalesData
。另外,请注意,在这种情况下,变量s
是本地 nonstatic。
接下来因为你:
- 没有使用类内初始化器来初始化
unitsSold
和revenue
- 没有使用建构式初始化器串列来初始化
unitsSold
和revenue
这 2 个变量具有不确定的值。并且使用这些未初始化的变量会导致未定义的行为。
这意味着当你写:
print(cout, s);//this calls print function
在print
函式体内你有:
os << "ISBN :\'" << item.isbn() << "\', Units Sold :" << item.unitsSold
<< ", Revenue :" << item.revenue << ", Avg. Price :"
<< item.avgPrice() << std::endl; //this is undefined behavior
因此,在上述宣告你正在使用的未初始化变量unitsSold
和revenue
这会导致不确定的行为。
这就是您在这种情况下看到这些数字(垃圾值)的3417894856
原因4.66042e-310
。所以不要依赖程序的输出,因为它具有未定义的行为。
案例二
现在让我们考虑 static SalesData s2;
从静态区域变量的初始化档案:
现在从零初始化档案开始:
这是最相关的部分:
零初始化的效果是:
让我们将上面参考的这些陈述句应用于您的示例 static SalesData s2;
在这种情况下,变量s2
是区域静态的。这里发生了两件事:
- 变量
s2
初始化为零。这意味着它的所有非静态资料成员都喜欢unitsSold
并根据上面参考的陈述句revenue
设定为。0
这就是在这种情况下输出数字全部0
而不是一些垃圾值的原因。 - 接下来,使用默认建构式
s2
对变量进行默认初始化。
1有关未定义行为的更技术上准确的定义,请参见此处提到:对程序的行为没有限制。
uj5u.com热心网友回复:
具有静态存盘持续时间的变量在其动态初始化阶段之前被初始化为零。
unitsSold
并且revenue
默认初始化。这使它们未初始化。在静态存盘的情况下,之前的零初始化成立。在自动存盘的情况下,它们具有不确定的值。读取不确定的值会导致程序的未定义行为。
0 评论