Разница между «новым Foo ()» и «& Foo ()» в качестве параметров - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть несколько вопросов относительно разницы между ключевым словом new и & в определенном контексте.

Допустим, это мой код:

struct Base {};
struct Foo : Base {};
struct Storage
{
    void save(Base * object) {}
    Base * content;
};

int main()
{
    Storage s1, s2;
    s1.save(new Foo());
    s2.save(&Foo());
}

После выполненияиз main s1 будет содержать указатель на объект типа Foo.И все же s2 будет содержать указатель на объект типа Base.s2.content будет указывать только на объект типа Foo до тех пор, пока метод сохранения не завершит выполнение.

Пожалуйста, исправьте меня, если я ошибаюсь:

Насколько я понимаю new Foo()создает указатель на новый объект типа Foo.&Foo(), с другой стороны, сначала создает новый объект типа Foo, а затем указывает на него.

В чем тогда разница между new Foo() и &Foo()?Очевидно, что оба дают вам указатель на существующий объект типа Foo.

Почему объект, созданный с помощью new Foo(), сохраняется после выполнения метода save, тогда как объект, созданный с помощью &Foo(), не сохраняется?

Может быть, &Foo() создает временный объект, который перестанет существовать после выполнения сохранения?Если да, как я могу продлить жизнь созданного объекта с помощью &Foo(), чтобы заставить его жить (по крайней мере) до уничтожения s2?

Редактировать 1: Большое спасибо за быстрые ответы!Я просто использую Visual Studio, так что, возможно, &Foo() компиляция - это что-то особенное для Microsoft ...

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

В чем же тогда разница между "new Foo()" и "&Foo()"?Очевидно, что оба дают вам указатель на существующий объект типа Foo.

Почему объект, созданный с помощью "new Foo()", сохраняется после выполнения метода сохранения, тогда как объект, созданный с помощью "&Foo()", не сохраняется?


new Foo()

new Foo();

Создает динамически размещаемый Foo объект и возвращает указатель, указывающий на этот объект.Динамически размещенные объекты будут сохраняться до тех пор, пока они явно не будут удалены программистом:

Foo* foo = new Foo();
delete foo; // delete the object.

&Foo()

Foo();

Это создает объект Foo с использованием автоматическое хранение .Это означает, что его время жизни, когда объект удаляется, определяется областью, в которой он находится:

{
  Foo foo{}; // foo lives in automatic storage.
} // end of scope, foo dies

В вашем случае вы создаете новый объект Foo и передаете адресэтого анонимного объекта на Storage::save.Этот объект будет уничтожен в конце полного выражения.Это в основном означает, что после s2.save() возврат вашего объекта будет уничтожен, а указатель, указывающий на него в s2, будет зависать, и разыменование будет неопределенным поведением.


Если да, то какМогу ли я продлить жизнь объекта, созданного через "& Foo ()", чтобы заставить его жить (по крайней мере) до уничтожения s2?

Вы не можете.Вам, вероятно, нужен интеллектуальный указатель, такой как std::unique_ptr.


Обратите внимание, что получение временного адреса не является стандартным, и поэтому этот код несовместим с самого начала.Ваш компилятор, вероятно, использует расширение, чтобы разрешить это.MSVC известен тем, что разрешил это.

0 голосов
/ 30 декабря 2018

Выражение Foo() создает новый временный объект, и использование оператора address-of & для этого временного объекта приведет к ошибке компилятора, поскольку ему не разрешено получать адрес временногоподобные объекты (Foo() - это rvalue , и оператор адреса-адреса не может использоваться для них).

С помощью new Foo вы создаете non временный объект, и результатом является указатель на этот объект.Время жизни этого объекта до тех пор, пока вы явно не delete его.И если вы не delete это, то у вас будет утечка памяти.

...