在 C++11 中引入了一个新特性,程序员可以在类定义中初始化类成员变量,见下面的代码:
struct foo
{
int size = 3;
int id = 1;
int type = 2;
unsigned char data[3] = {'1', '2', '3'};
};
这个初始化是在编译期间发生的,还是这个特性只是语法糖,成员变量在默认构造函数中初始化?
最佳答案
首先是的,如前所述,它是语法糖。但由于规则可能难以记住,这里有一个合乎逻辑的实验,可以帮助您弄清楚编译时会发生什么,什么不会发生
你的 c++11 类在类初始化器中具有特色
struct foo { int size = 3; };
还有一个类(class)可以帮助我们进行实验
template<int N>
struct experiment { enum { val = N }; };
让我们的假设 H0 是初始化确实发生在编译时,那么我们可以这样写
foo a;
experiment<a.size> b;
不走运,我们无法编译。有人可能会争辩说失败是由于 foo::size
是非恒定的,所以让我们尝试使用
struct foo { const int size = 3; }; // constexpr instead of const would fail as well
再次,正如 gcc 通知我们的那样
the value of ‘a’ is not usable in a constant expression
experiment b;
或者(更清楚)visual studio 2013 告诉我们
error C2975: 'N' : invalid template argument for 'example', expected compile-time constant expression
因此,我们必须丢弃 H0 并推断 初始化不会在编译时发生。
编译时会发生什么
有一种旧语法可以解决问题
struct foo { static const int size = 3; };
Now this compiles但请注意,这(技术上和逻辑上)不再是 in class 初始化。
为了说明一点我不得不撒谎,但现在要揭露全部真相:消息错误意味着 a
是真正的问题。你看,因为你有一个对象的实例(Daniel Frey 也提到了这一点)内存(对于成员)必须被初始化(在运行时)。如果成员是 (const
) static
,如最后一个示例,那么它不是 (ny) 类的子对象的一部分,您可以在编译时进行初始化时间。
关于c++ - 类成员初始化是在编译时还是运行时进行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23207350/