gpt4 book ai didi

c++ - 类静态变量初始化的规则是什么?

转载 作者:太空狗 更新时间:2023-10-29 23:12:40 25 4
gpt4 key购买 nike

我有一些遗留代码,我需要为消息添加一个新类(这与我的问题无关)。但事实证明,我需要声明一个空的构造函数才能初始化一些静态。不是默认构造函数或编译器提供的,而是用户定义的空。我试图将代码缩减为 MWE,这里是我得到的:

#include <iostream>

using namespace std;

struct Test
{
Test() {cout << "Test::Test()" << "\n";}
void dummy(){}
};

template<typename T>
struct Message
{
Message()
{
test.dummy(); // this call have to be here in order to initialize Test, but why?
}

static Test test;
};

template<typename T>
Test Message<T>::test;

struct A : public Message<A>
{
//A(){} // uncomment this (and comment the default one) to call the Test constructor
A() = default;
};

int main()
{
}

这是发生了什么:

  • 程序本身是空的,即没有创建任何实例。
  • A 类有一个 CRTP,这似乎对示例很重要。
  • A 的基类有一个静态声明,我希望调用它的构造函数。
  • 有一个对函数的虚拟调用,它什么都不做,但也很关键。

问题是,如果我不提供自定义构造函数,则永远不会调用静态构造函数。我不明白为什么我需要这个?默认值或编译器生成有什么区别?为什么我需要调用虚拟函数?

我相信这是有规则的。我用不同版本的 gcc 和 clang 检查了它——行为是一样的。我非常感谢指向标准/文档的链接。

最佳答案

如果您将 A 构造函数保留为默认值并且从不调用它,则无需生成它,因此也无需创建 test。如果您在定义时明确默认它,调用 A 构造函数或访问 A::test 它将被正确初始化。

12.1 Constructors [class.ctor]

7 A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration.

struct A : public Message<A>
{
A() = default; // no constructor is emitted unless A is instantiated

A(); // declaration
};

A::A() = default; // explicit default definition

int
main()
{
A a; // instantiation
A::test; // just explicitly access test so it is initialized regardless of A constructor
}

关于c++ - 类静态变量初始化的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44341568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com