关于 C++11 及之后的 new T() 和 new T 之间的一些具体区别的问题
Question about some specific differences between new T() and new T in C++11 and afterwards
请注意:您可能认为 post 与 this old post 重复。但上述 post 是 超过 12 年 之前和 none 的答案 提到了 C++11 及之后.
还有,我的问题是关于得票最多的答案的评论,我的问题是关于详细代码下面的片段。
根据 this answer 的评论,[强调我的]:
With C++11 you can do this in stack too; B obj{}; will make the object value-initialized (to 0s) as opposed to B obj; which will be default-initialized (garbage).
但是对于this code snippet来说,他们之间似乎并没有什么区别。
提示:请注意上述代码片段的输出。
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
Question about some specific differences between new T() and new T
new T()
是值初始化。对于聚合 类 例如 Line
和 Point<T>
这意味着所有子对象都被值初始化。对于 double*
和 int
等原始对象,这意味着零初始化。
new T
是默认初始化。对于聚合 类 例如 Line
和 Point<T>
这意味着所有子对象都被默认初始化。对于 double*
和 int
这样的原始对象,这意味着 没有 初始化。如果一个对象没有初始化1,那么它有一个不确定的值。这意味着它们的价值是不确定的。如果一个程序读取一个不确定的值(非窄字符类型),那么该程序的行为是 undefined。这是要避免的。不要这样做。
示例程序读取不确定的值,其行为未定义。
in C++11 and afterwards
自从 C++03 将值初始化添加到语言以来,这些方面没有发生变化。
与示例不直接相关,但在 C++11 中为值初始化添加了新语法:new T {}
(除了使用花括号进行临时和变量初始化的类似语法之外)。
1 请注意,无论您使用何种语法,具有静态存储持续时间的对象在任何其他初始化之前都是零初始化。
请注意:您可能认为 post 与 this old post 重复。但上述 post 是 超过 12 年 之前和 none 的答案 提到了 C++11 及之后.
还有,我的问题是关于得票最多的答案的评论,我的问题是关于详细代码下面的片段。
根据 this answer 的评论,[强调我的]:
With C++11 you can do this in stack too; B obj{}; will make the object value-initialized (to 0s) as opposed to B obj; which will be default-initialized (garbage).
但是对于this code snippet来说,他们之间似乎并没有什么区别。 提示:请注意上述代码片段的输出。
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
Question about some specific differences between new T() and new T
new T()
是值初始化。对于聚合 类 例如 Line
和 Point<T>
这意味着所有子对象都被值初始化。对于 double*
和 int
等原始对象,这意味着零初始化。
new T
是默认初始化。对于聚合 类 例如 Line
和 Point<T>
这意味着所有子对象都被默认初始化。对于 double*
和 int
这样的原始对象,这意味着 没有 初始化。如果一个对象没有初始化1,那么它有一个不确定的值。这意味着它们的价值是不确定的。如果一个程序读取一个不确定的值(非窄字符类型),那么该程序的行为是 undefined。这是要避免的。不要这样做。
示例程序读取不确定的值,其行为未定义。
in C++11 and afterwards
自从 C++03 将值初始化添加到语言以来,这些方面没有发生变化。
与示例不直接相关,但在 C++11 中为值初始化添加了新语法:new T {}
(除了使用花括号进行临时和变量初始化的类似语法之外)。
1 请注意,无论您使用何种语法,具有静态存储持续时间的对象在任何其他初始化之前都是零初始化。