1

考虑以下具有用户定义的默认 ctor 的类。

class TestClass {
public:
    TestClass()
    :data_(999) {
    }
    double getData() const {
        return data_;
    }

private:
    double data_;
};

然后我们创建对象:

TestClass *p2 = new TestClass();
TestClass *p1 = new TestClass;

在任何情况下使用上述 2 个语句有什么区别?

谢谢,

4

1 回答 1

0

简短的回答:没有区别。

更长的答案:§5.3.4,15 指出

创建类型对象的new表达式T按如下方式初始化该对象:
— 如果省略 new-initializer,则该对象是默认初始化的(第 8.5 节);如果不执行初始化,则对象具有不确定的值。
— 否则,根据第 8.5 节的初始化规则解释 new-initializer 以进行直接初始化。

§8.5,16 说

如果初始值设定项是 (),则对象是值初始化的

现在什么是值初始化和默认初始化,由 §8.5,5-7 定义:

对T 类型的对象或引用进行零初始化
意味着: —如果 T 是标量类型 (3.9),则对象设置为值 0(零),[...]
— 如果 T 是 a(可能是 cv-限定)非联合类类型,每个非静态数据成员和每个基类子对象都初始化为零,填充初始化为零位;
— 如果 T 是(可能是 cv 限定的)联合类型,则对象的第一个非静态命名数据成员被零初始化,填充被初始化为零位;
— 如果 T 是数组类型,则每个元素都初始化为零;
— 如果 T 是引用类型,则不执行初始化。

默认初始化T类型的对象意味着:
如果 T 是(可能是 cv 限定的)类类型(第 9 条),则 T 的默认构造函数称为 [...]
— 如果 T 是数组类型,每个元素是默认初始化的;
否则,不执行初始化。 [...]

对T 类型的对象进行值初始化意味着:
如果 T 是具有用户提供的构造函数 (12.1) 的(可能是 cv 限定的)类类型(第 9 条),则 T 的默认构造函数称为 [... ]
— 如果 T 是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,则该对象是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
— 如果 T 是一个数组类型,那么每个元素都是值初始化的;
否则,对象被零初始化。

(强调我的)

总之,由于你的类有一个用户提供的默认构造函数,值初始化和默认初始化是相同的,所以两个新表达式给出相同的行为,即调用默认构造函数。

例如 ints 是另一回事:

int *p2 = new int(); // value-initialized, i.e. zero-initialized, *p2 is 0
int *p1 = new int;   // default-initialized, i.e. no initialization. *p1 is some garbage. Or whatever.
于 2013-05-02T14:10:37.040 回答