Подтвердить что ты не робот

"новый" оператор в С++, указательный вопрос

Тупой вопрос, но всякий раз, когда вы вызываете новое, у вас всегда есть указатель?

SomeClass *person = new SomeClass();

И это потому, что вам нужен указатель, указывающий на это новое пространство памяти, которое было выделено для человека переменной SomeClass? Спасибо!

4b9b3361

Ответ 1

Если new завершается успешно, он всегда возвращает указатель (если он не завершается успешно, генерируется исключение, и ничего не возвращается).

Указатель относится к объекту, который был создан, или в случае с массивом, указателю на первый элемент массива.

Ответ 2

Да, всегда указатель. Даже если вы хотите перегрузить новый, тип возврата должен быть void *.
И вы правы с целью

Ответ 3

new создает объект в куче, и все, что он может вернуть, это его адрес - указатель.

Ответ 4

Да. Если вы спрашиваете, почему он не возвращает ссылку вместо этого, поскольку ссылки лучше, чем указатели, ответ - историческое наследие.

Когда С++ находилась в разработке, если машине не удалось получить память для объекта, был возвращен специальный указатель NULL. Вот как это делается в C:

SomeClass *person;
person = (SomeClass*) malloc( sizeof( SomeClass ) );
if ( person == NULL ) fprintf( stderr, "no more people allowed!" );

В стандартном С++ ошибки возвращаются вместо исключения:

try {
    SomeClass *person = new SomeClass;
    // do something
} catch ( std::bad_alloc ) {
    std::cerr << "no more people!" << std::endl;
} catch ( ... ) {
    // using exceptions allows for other errors
    // from inside SomeClass::SomeClass too
}

Вы все еще можете сделать это старомодным способом, но с nothrow:

SomeClass *person = new( std::nothrow ) SomeClass;
if ( person == NULL ) std::cerr << "no more people allowed!" << std::endl;

Результат: это вполне разумный и хороший стиль:

SomeClass &person = * new SomeClass; // don't need no stinkin pointers!

Ответ 5

Новое выражение возвращает указатель, но вы можете использовать его с классами "умного указателя" (например, из Boost). Итак:

boost::shared_ptr<SomePerson> person(new SomePerson);

Я должен также указать, что, хотя вы можете использовать круглые скобки, если вы исходите из фона Java, в С++, круглые скобки не нужны при использовании конструктора по умолчанию. Так, например, обычно при записи по умолчанию new T записывается new T, но при написании объекта с использованием конструктора, отличного от значения по умолчанию, записывается new T(param) или new T(param1,...,paramN).

Да, это правильно; теоретически можно написать (новый SomePerson) → doSomething(), но это будет утечка памяти; С++ не содержит сборку мусора, поэтому необходимо сохранить результат нового выражения в чем-либо (указатель или интеллектуальный указатель), чтобы его можно было правильно освободить.