c++ - 类成员初始化是在编译时还是运行时进行?

标签 c++ c++11

在 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/

相关文章:

c++ - qt creator 项目更改目录

c++ - C++ 类中更多函数的效果

c++ - 赋予容器其子代的所有权,但让子代使用智能指针存储对其父代的引用

c++11:完美转发中的常量

c++11 - 编译器声明的隐式移动构造函数

c++ - 是否有 "safe"static_cast 替代方案?

c++ - 如何查找并替换存储在 char 数组中的字符串?

c++ - 不是所有控制路径都返回值吗?

c++ - 对于具有引用返回类型的搜索算法,默认返回值应该是什么?

c++ - C++11 基于范围的 for 循环如何知道数组大小?