«новый» оператор в c ++, вопрос указателя - PullRequest
12 голосов
/ 28 апреля 2010

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

SomeClass *person = new SomeClass();

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

Ответы [ 5 ]

15 голосов
/ 28 апреля 2010

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

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

3 голосов
/ 28 апреля 2010

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

2 голосов
/ 28 апреля 2010

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

1 голос
/ 28 апреля 2010

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

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

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

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

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!
0 голосов
/ 28 апреля 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...