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.