【发布时间】:2017-05-04 12:01:25
【问题描述】:
我有一些遗留代码,我需要为消息添加一个新类(这与我的问题无关)。但事实证明,我需要声明一个空的构造函数才能初始化一些静态。不是默认构造函数或编译器提供的,而是用户定义的空。我试图将代码简化为 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构造函数的输出。如果我省略构造函数或声明它default我什么也观察不到。您可以通过评论/取消评论呼叫来检查它here。