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

c – 类静态变量初始化的规则是什么?,第1张

概述我有一些遗留代码,我需要为消息添加一个新类(这与我的问题无关).但事实证明,我需要声明一个空构造函数,以便初始化一些静态.不是默认构造函数或编译器提供的,而是用户定义的空.我试图将代码减少到MWE,在这里得到的结果是: #include <iostream>using namespace std;struct Test{ Test() {cout << "Test::Test() 我有一些遗留代码,我需要为消息添加一个新类(这与我的问题无关).但事实证明,我需要声明一个空构造函数,以便初始化一些静态.不是默认构造函数或编译器提供的,而是用户定义的空.我试图将代码减少到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构造函数或访问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 deFinitionintmain(){    A a; // instantiation    A::test; // just explicitly access test so it is initialized regardless of A constructor}
总结

以上是内存溢出为你收集整理的c – 类静态变量初始化的规则是什么?全部内容,希望文章能够帮你解决c – 类静态变量初始化的规则是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1217685.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存