请注意 :您可能会认为这篇文章与旧文章重复。但上述帖子是12年前的,没有一个答案提到C++11以及之后的。
更重要的是 ,我的问题是关于得票最多的答案的评论,我的问是关于下面的详细代码片段。
根据这个答案的评论,它说(强调我的):
使用C++11,您也可以在堆栈中执行此操作;B obj{};将使对象值初始化(为0s),而不是B obj;它将被默认初始化(垃圾)。
但是对于这个代码片段,它们之间似乎没有区别。提示:注意上述代码片段的输出。
new Line()
是默认初始化的,但它实际上不是垃圾。
下面是前面提到的代码片段:
#include <utility>
#include <iostream>
#include <string>
template<typename T>
struct Point {
T x;
T y;
};
struct Line{
Point<double> head;
Point<double> tail;
double *demo;
int color;
//std::string comment;
};
template<typename T>
std::ostream& operator<<(std::ostream& os, const Point<T>& point)
{
os << "(" << point.x <<"," << point.y <<")";
return os;
}
std::ostream& operator<<(std::ostream& os, const Line& line)
{
os << "head: " << line.head << std::endl;
os << "head: " << line.tail << std::endl;
os << "demo=" << static_cast<void*>(line.demo) << std::endl;
os << "color=" << line.color << std::endl;
//os << "string=" << line.comment << std::endl;
return os;
}
int main()
{
auto ptr2lineWithBracket = new Line();
std::cout << *ptr2lineWithBracket;
std::cout << "==================" << std::endl;
auto ptr2lineWithout = new Line;
std::cout << *ptr2lineWithout;
}
这是输出:
head: (0,0)
head: (0,0)
demo=0
color=0
==================
head: (0,0)
head: (0,0)
demo=0
color=0
关于新T()和新T 之间某些特定差异的问题
new T()
是值初始化。对于聚合类(如Line
和Point<T>
),这意味着所有子对象都进行了值初始化。对于诸如double*
和int
之类的基元对象,这意味着零初始化。
new T
是默认初始化。对于聚合类(如Line
和Point<T>
),这意味着所有子对象都默认初始化。对于诸如double*
和int
之类的基元对象,这意味着没有初始化。如果一个对象没有初始化1,那么它有一个不确定的值。这意味着它们的价值是不确定的。如果程序读取了一个不确定的值(非窄字符类型),则程序的行为为未定义。这是要避免的。不要这样做。
示例程序读取不确定的值,其行为是未定义的。
在C++11中以及之后的中
自从C++03将值初始化添加到语言中以来,这些方面没有任何变化。
与示例没有直接关系,但在C++11中为值初始化添加了一个新语法:new T {}
(除了使用大括号进行临时和变量初始化的类似语法之外)。
1注意,无论使用何种语法,具有静态存储持续时间的对象在任何其他初始化之前都是零初始化的。