Разное временный объект T()

Рассмотрим этот код:

int main()
{
    int i(6); //this will result in i==6,but consider next initializations

    int j(int()); 

    T * p2 = new T(); 
}

Я обнаружил, что значение j равно 1, но оно должно быть 0, потому что int() является временным значением, равным 0.

Кроме того, синтаксис оператора newnew typename, но здесь T() будет временным объектом, а не именем типа.


person T.J.    schedule 19.02.2012    source источник
comment
Вы запутались, new T() динамически выделяет объект T и инициализирует его значением, а не создает временный. Что вы на самом деле пытаетесь сделать.   -  person Ben Voigt    schedule 19.02.2012
comment
Это должно быть закрыто, прямо сейчас вопросов нет, и если вопрос будет добавлен, это будет либо ссылка в ответе Наваза, либо stackoverflow.com/questions/2671532/ и stackoverflow.com/questions/6298001/   -  person Ben Voigt    schedule 19.02.2012
comment
На самом деле, TJ только что задал один из этих вопросов два часа назад: >stackoverflow.com/questions/9346687/ В следующий раз прочитайте ссылки на вопросы, оставленные в комментариях, TJ!   -  person Ben Voigt    schedule 19.02.2012


Ответы (2)


int j(int()); 

Это не объявляет объект. Вместо этого он объявляет функцию, которая принимает функцию в качестве аргумента и возвращает int. Тип функции, которую она принимает в качестве аргумента, таков:

 typedef int (*funtype)();

То есть функция, которая возвращает int и ничего не принимает в качестве аргумента.

Разбор такого объявления обычно известен как:


А в синтаксисе new T() не создает временный объект. Это не то, как это должно быть видно. Вместо этого вы должны просмотреть все выражение new T(), которое сначала выделяет память для объекта типа T, а затем создает объект в этой памяти. Если T является определяемым пользователем типом, то он вызывает конструктор по умолчанию для создания объекта после выделения памяти.

person Nawaz    schedule 19.02.2012
comment
И исправление состоит в том, чтобы либо использовать дополнительные скобки, чтобы сделать его недопустимым объявлением функции: int j((int()));, либо избегать синтаксиса: int j = int();. - person GManNickG; 19.02.2012
comment
@nawaz: а как насчет второго вопроса - person T.J.; 19.02.2012

Также синтаксис для нового оператора: typename *variable_name = new typename, но здесь T() будет временным объектом, а не именем типа.

Подобно самому неприятному анализу, T() имеет разные значения в зависимости от контекста. Он не всегда создает временный объект, а обычно инициализирует некоторый новый анонимный объект или подобъект. Объект может быть

  • временное, если T() находится в выражении,
  • базовый подобъект, если T() появляется перед телом в конструкторе или
  • референт указателя, если T() появляется после new. Обратите внимание, что указатель имеет имя, но объект является анонимным.

new T и new T() делают несколько разные вещи: для некоторых типов new T оставляет значения неинициализированными. (Официальный термин — инициализация по умолчанию.) Для базовых подобъектов или временных объектов не существует соответствующей грамматической конструкции: базовые подобъекты инициализируются по умолчанию путем пропуска инициализатора, а временные объекты не могут быть инициализированы по умолчанию. . Разница невелика, так как во всех этих случаях конструктор будет вызываться, если вы его определили, а конструктор всегда должен быть определен, и он всегда должен инициализировать все элементы. Исключениями являются основные типы, такие как int, и простые структуры, такие как std::array<char, 1000>.

Чтобы быть в безопасности, лучше избегать new T в пользу new T(), просто чтобы убедиться, что все хорошо обнуляется в отсутствие конструктора.

person Potatoswatter    schedule 19.02.2012