拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 为什么用户定义型别别的静态和区域变量的合成默认建构式的行为不同?

为什么用户定义型别别的静态和区域变量的合成默认建构式的行为不同?

白鹭 - 2022-01-24 1944 0 0

在下面的示例程序中,

为什么用户定义的型别别的静态和自动变量的输出不同?

/* 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

接下来因为你:

  1. 没有使用类内初始化器来初始化unitsSoldrevenue
  2. 没有使用建构式初始化器串列来初始化unitsSoldrevenue

这 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

因此,在上述宣告你正在使用的未初始化变量unitsSoldrevenue这会导致不确定的行为

这就是您在这种情况下看到这些数字(垃圾值)的3417894856原因4.66042e-310所以不要依赖程序的输出,因为它具有未定义的行为。

案例二

现在让我们考虑 static SalesData s2;

静态区域变量的初始化档案

现在从零初始化档案开始:

这是最相关的部分:

零初始化的效果是:

让我们将上面参考的这些陈述句应用于您的示例 static SalesData s2;

在这种情况下,变量s2区域静态的。这里发生了两件事:

  1. 变量s2初始化为零。这意味着它的所有非静态资料成员都喜欢unitsSold根据上面参考的陈述句revenue设定为。0这就是在这种情况下输出数字全部0 而不是一些垃圾值的原因。
  2. 接下来,使用默认建构式s2对变量进行默认初始化

1有关未定义行为的更技术上准确的定义,请参见此处提到:对程序的行为没有限制

uj5u.com热心网友回复:

具有静态存盘持续时间的变量在其动态初始化阶段之前被初始化为零。

unitsSold并且revenue默认初始化。这使它们未初始化。在静态存盘的情况下,之前的零初始化成立。在自动存盘的情况下,它们具有不确定的值。读取不确定的值会导致程序的未定义行为。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *