C++默认初始化和值初始化:哪个是哪个,啥时候调用以及如何可靠地初始化一个模板类型成员
Posted
技术标签:
【中文标题】C++默认初始化和值初始化:哪个是哪个,啥时候调用以及如何可靠地初始化一个模板类型成员【英文标题】:C++ default initialization and value initialization: which is which, which is called when and how to reliably initialize a template-type memberC++默认初始化和值初始化:哪个是哪个,什么时候调用以及如何可靠地初始化一个模板类型成员 【发布时间】:2011-12-27 16:58:09 【问题描述】:我的问题与this 和其他几个类似的问题有些重叠。这些有一些很好的答案,但我已经阅读了它们,但我仍然感到困惑,所以请不要认为这个问题是重复的。
所以,我有以下代码:
class A
public: int _a;
void main()
A inst1;
A* inst2 = new A;
A* inst3 = new A();
_a
在inst1
和inst2
中未初始化,在inst3
中初始化为0
。
哪个初始化被称为哪个,为什么代码会这样工作?请考虑到我手头没有 C++ 03 标准,但我有最后的 C++ 11 草案(不过我正在按照 '03 标准编程),所以引用 '03 标准或引用 '11非常欢迎。
P。 S. 这项研究的最初任务是正确地初始化任意模板类型T
的成员。
【问题讨论】:
Value-initializing an automatic object?的可能重复 对于即将到来的用户也检查一下***.com/questions/6032638/default-variable-value 【参考方案1】:没那么难:
A x;
A * p = new A;
这两个是默认初始化。由于您没有用户定义的构造函数,这仅意味着所有成员都是默认初始化的。默认初始化像int
这样的基本类型意味着“没有初始化”。
下一步:
A * p = new A();
这是值初始化。 (我认为在 C++98/03 中不存在这个的自动版本,虽然在 C++11 中你可以说 A x;
,并且这个 brace-initialization 变成了 value-initialization . 此外,A x = A();
尽管是复制初始化,但实际上足够接近,或者A x((A()))
尽管是直接初始化。)
同样,在您的情况下,这只是意味着所有成员都进行了值初始化。基本类型的值初始化意味着零初始化,这反过来意味着变量被初始化为零(所有基本类型都有)。
对于类类型的对象,默认初始化和值初始化都会调用默认构造函数。然后会发生什么取决于构造函数的初始化器列表,并且游戏会递归地为成员变量继续。
【讨论】:
我了解它对类的工作原理(它们有构造函数,无论是显式定义的还是默认的)。只有内置类型对象让我感到困惑。感谢您的解释。但是,我没有得到关于复制初始化和直接初始化的评论。你不是把它们弄混了吗? @VioletGiraffe:我希望不会。不要将作为语法概念的“初始化”与作为对象模型一部分的“构造”混淆。前者有时会导致后者,但有一些重叠和令人困惑的术语在起作用。 应该将A x = A((A()))
改为A x( A() );
吗?
@Kerrek SB:那么可能是A x( (A()) );
?不然还是copy-initialization不是吗?
@VioletGiraffe:因为A x(A())
将x
声明为返回A
的函数,并采用一个参数,该参数本身是一个(指向a)函数,返回A
并且不带任何参数。这不是你认为你要声明的内容:-)【参考方案2】:
是的,A inst4 ();
被视为函数声明。 std::string str();
应该是相同的(即我认为您错误地认为它有效)。
显然(来自here),C++03 将使inst3._a
为 0,但 C++98 会使其未初始化。
【讨论】:
你说得对,它们都是函数声明,我没有注意到警告。我认为这应该是一个错误。以上是关于C++默认初始化和值初始化:哪个是哪个,啥时候调用以及如何可靠地初始化一个模板类型成员的主要内容,如果未能解决你的问题,请参考以下文章
C++:首先调用/初始化哪个?其成员变量的类构造函数或构造函数?
stm32启动的时候默认的是哪个时钟,是RC还是外部晶体?何以更改默认时钟么?