首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在类中,成员初始化是在编译时进行还是在运行时进行?

在类中,成员初始化是在编译时进行还是在运行时进行?
EN

Stack Overflow用户
提问于 2014-04-21 22:49:53
回答 5查看 6.2K关注 0票数 28

在C++11中引入了一个新特性,程序员可以在类的定义中初始化类成员变量,请参见下面的代码:

代码语言:javascript
复制
struct foo
{ 
  int size = 3;
  int id   = 1;
  int type = 2;
  unsigned char data[3] = {'1', '2', '3'};
};

这个初始化是在编译期间进行的还是这个特性只是语法糖,成员变量是在默认构造函数中初始化的呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-04-23 20:05:33

首先,是的,正如前面所说的,它是句法糖。但是,由于规则太难记住了,下面是一个逻辑实验,可以帮助您了解编译时发生的事情和什么不是

您的c++11类具有类初始化器中的特性。

代码语言:javascript
复制
struct foo { int size = 3; };

另一节课将帮助我们做实验

代码语言:javascript
复制
template<int N>
struct experiment { enum { val = N }; };

假设H0假设初始化在编译时确实发生,那么我们可以编写

代码语言:javascript
复制
foo                a;
experiment<a.size> b;

没有运气,我们没能编好。人们可能会争辩说,失败是由于foo::size是非常数的,所以让我们尝试一下

代码语言:javascript
复制
struct foo { const int size = 3; }; // constexpr instead of const would fail as well

再一次,gcc告诉我们

‘a’的值在常量表达式中不可用 实验b;

或者(更清楚地)2013年视频工作室告诉我们

错误C2975:'N‘:“示例”的无效模板参数,预期编译时常量表达式

因此,我们必须放弃H0,并推断在编译时不会发生初始化。

在编译时会发生什么?

有一种旧的语法能起作用

代码语言:javascript
复制
struct foo { static const int size = 3; };

现在这会编译,但请注意,这在技术上和逻辑上都不再存在于类初始化中。

为了说明这一点,我不得不撒点小谎,但现在要公开整个事实:消息错误意味着才是真正的问题。您知道,因为您有一个对象的实例(Daniel也提到了这个),所以内存(对于成员)必须被初始化(在运行时)。如果成员是(const) static,如最后一个示例所示,那么它不是(Ny)类的子对象的一部分,您可以在编译时进行初始化。

票数 28
EN

Stack Overflow用户

发布于 2014-04-21 23:16:53

成员变量的类内初始化符是在构造函数初始化项列表中写入它们的语法糖,除非已经存在显式初始化项,在这种情况下,它们将被忽略。

静态const成员的类初始化符用于常量文本,仍然需要定义(尽管没有初始化)。

C++具有来自C的“仿佛”-rule,因此任何导致指定的观察行为的行为都是允许的。

具体来说,这意味着静态对象可以在编译时初始化.

票数 3
EN

Stack Overflow用户

发布于 2014-04-21 22:53:32

只是句法上的糖。还请考虑实例通常意味着必须用正确的值初始化内存。仅仅因为这些值提供了不同的语法,就不会改变内存需要初始化的事实--这是在运行时发生的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23207350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档