2 оператора, создающие объекты с регулярным новым выражением, какая разница?

Рассмотрим следующий класс с пользовательским ctor по умолчанию.

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

private:
    double data_;
};

Затем мы создаем объекты:

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

Какая разница для использования 2 операторов выше в любых условиях?

Спасибо,

1 ответ

Решение

Краткий ответ: без разницы.

Более длинный ответ: §5.3.4,15 гласит, что

Новое выражение, которое создает объект типа T инициализирует этот объект следующим образом:
- Если новый инициализатор опущен, объект инициализируется по умолчанию (§8.5); если инициализация не выполняется, объект имеет неопределенное значение.
- В противном случае новый инициализатор интерпретируется в соответствии с правилами инициализации §8.5 для прямой инициализации.

И §8.5,16 говорит

Если инициализатором является (), объект инициализируется значением.

Теперь, что такое инициализация значения и инициализация по умолчанию, определяется в §8.5,5-7:

Инициализация нуля объекта или ссылки типа T означает:
- если T скалярного типа (3.9), объекту присваивается значение 0 (ноль), [...]
- если T является (возможно, cv-квалифицированным) типом несоединения классов, каждый нестатический элемент данных и каждый подобъект базового класса инициализируются нулями, а заполнение инициализируется нулевыми битами;
- если T является (возможно, cv-квалифицированным) типом объединения, первый нестатический именованный элемент данных объекта инициализируется нулями, а заполнение инициализируется нулевыми битами;
- если T является типом массива, каждый элемент инициализируется нулями;
- если T является ссылочным типом, инициализация не выполняется.

По умолчанию инициализировать объект типа T означает:
- если T является (возможно, cv-квалифицированным) типом класса (раздел 9), конструктор по умолчанию для T называется [...]
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- иначе инициализация не выполняется. [...]

Инициализировать значение объекта типа T означает:
- если T является (возможно, cv-квалифицированным) типом класса (раздел 9) с предоставленным пользователем конструктором (12.1), тогда конструктор по умолчанию для T называется [...]
- если T является (возможно, cv-квалифицированным) типом класса, не являющимся объединением, без предоставленного пользователем конструктора, то объект инициализируется нулями и, если неявно объявленный конструктор T по умолчанию является нетривиальным, вызывается этот конструктор.
- если T является типом массива, то каждый элемент инициализируется значением;
- иначе объект инициализируется нулями.

(акцент мой)

Вместе, поскольку ваш класс имеет предоставленный пользователем конструктор по умолчанию, инициализация значения и инициализация по умолчанию одинаковы, поэтому оба новых выражения имеют одинаковое поведение, а именно вызывается конструктор по умолчанию.

Другое дело, например, с целыми числами:

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.
Другие вопросы по тегам