首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个静态类字段是否在创建之前就被使用了?

这个静态类字段是否在创建之前就被使用了?
EN

Stack Overflow用户
提问于 2017-02-10 07:10:55
回答 1查看 46关注 0票数 1

因此,我一直在尝试静态类字段(特别是常量字段),并将自己带入了……这一点:

代码语言:javascript
复制
#include <iostream>
#include <conio.h>

class Test {
public:
    Test() { std::cout << "Constructing (Default CTOR)\n"; }
    Test(int f) { std::cout << "Constructing (Int arg CTOR)\n"; }

    void method() const { std::cout << "Already constructed and being used\n"; }
};

class Stack {
public:
    // static const Test what{ 5 }; // - "element of type "const Test" can not have an initializer inside of a class"
    // const Test ok{ 5 }; // now it can (?)

    static const Test what;

    Stack() {
        what.method();
    }

    // Stack() : what{5} {} // can't do that because "what" will be dependent on object creation (which is not how static class fields roll)
};

Stack obj;

const Test Stack::what{};

int main()
{
    _getch();
    return 0;
}

输出:

显然,Stack中的static const Test what在实际创建之前就已经被使用了(?)。

在那之后,我运行了另一个测试:

代码语言:javascript
复制
#include <iostream>
#include <conio.h>

class Test {
public:
    int data;

    Test() { std::cout << "CONSTRUCTING (Default CTOR)\n"; } // notice, value-initialization of 'data' has been removed
    Test(int f) : data{ f } { std::cout << "CONSTRUCTING (Int arg CTOR)\n"; }

    void method() const { std::cout << "ALREADY CONSTRUCTED AND BEING USED :)\n" << data << std::endl; }
};

class Stack {
public:
    static const Test what;

    Stack() {
        what.method();
    }
};

Stack obj;

const Test Stack::what{ 5 };

int main()
{
    obj.what.method();

    _getch();
    return 0;
}

在这段代码中,我希望看到某种错误,但输出结果如下所示:

我对这里发生的事情有一些假设,但我不确定它们是否正确。所以,如果他们是,请纠正我。

以下是我的假设:

基本上,静态变量是在程序的最开始创建的(并且是值初始化的),并在程序的最后(当您实际关闭.exe时)销毁。在我的示例中,我在类Stack中有一个静态常量变量what,我认为它是在我的程序value-initialized开始时创建的。这就是为什么它的data字段被设置为0,我们可以使用它的方法。但我不认为这是正确的,因为它会将Constructing (Default CTOR)输出到控制台。所以我被困在那里了.

我也不明白为什么我第一个例子中的注释行是非法的。它们到底违反了静态/常量类字段的哪些规则?

如果你对我的例子中发生的事情有任何想法,请解释一下。

感谢您的关注。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-10 09:28:33

名称空间范围内(即不在函数内)的静态变量是按照其在源文件中的定义顺序构造的。此顺序仅适用于同一源文件中的变量之间,而不适用于不同源文件之间。

因此,obj总是在what之前构造。在调用构造函数之前,对具有构造函数的对象可以做的事情是有限的;调用成员函数不是其中之一(C++14 basic.life/5.2)。因此,在Stack的构造函数中调用what.method()会导致未定义的行为。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42148665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档