关于 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()是值初始化。对于聚合 类 例如 LinePoint<T> 这意味着所有子对象都被值初始化。对于 double*int 等原始对象,这意味着零初始化。

new T 是默认初始化。对于聚合 类 例如 LinePoint<T> 这意味着所有子对象都被默认初始化。对于 double*int 这样的原始对象,这意味着 没有 初始化。如果一个对象没有初始化1,那么它有一个不确定的值。这意味着它们的价值是不确定的。如果一个程序读取一个不确定的值(非窄字符类型),那么该程序的行为是 undefined。这是要避免的。不要这样做。

示例程序读取不确定的值,其行为未定义。

in C++11 and afterwards

自从 C++03 将值初始化添加到语言以来,这些方面没有发生变化。

与示例不直接相关,但在 C++11 中为值初始化添加了新语法:new T {}(除了使用花括号进行临时和变量初始化的类似语法之外)。


1 请注意,无论您使用何种语法,具有静态存储持续时间的对象在任何其他初始化之前都是零初始化。