Возврат ссылки на конструктор объекта - PullRequest
0 голосов
/ 15 ноября 2011

Посмотрите на этот код:

Foo &Bar::Copy()
{
    return Bar();
}

Класс Bar наследуется от Foo, а Foo является абстрактным классом. Но когда я звоню Bar() и возвращаю его, безопасно ли это делать? Или я бы возвращал адрес локальной переменной, которая будет освобождена в конце функции Copy()?

Совет с благодарностью!

Ответы [ 3 ]

1 голос
/ 15 ноября 2011

При вызове Bar(); вы вызываете конструктор для неявного временного объекта, на который возвращается ссылка. Если вы намереваетесь создать функцию, подобную Clone(), типичным решением является создание клона в куче с помощью new. Вы можете использовать своего рода умный указатель, чтобы упростить управление жизненным циклом. Вы также можете применить ковариантный тип возвращаемого значения, чтобы избежать преобразования типов в некоторых случаях, используя подпись: Bar &Bar::Copy()

1 голос
/ 15 ноября 2011

Вы не возвращаете ctor. Bar(); вызывает ctor, создавая временный объект. Затем вы возвращаете ссылку на этот временный объект.

Поскольку у ctor в C ++ нет имени, вы не можете делать многие обычные вещи, которые вы могли бы делать с обычными функциями, например, получать / возвращать указатель на функцию. Не совсем понятно, чего вы на самом деле пытаетесь достичь, но если вы хотите вернуть что-то, что создаст объект, вам обычно нужно определить статическую функцию-член, которая вызывает ctor, и вернуть указатель на эту статическую функцию-член .

0 голосов
/ 15 ноября 2011

Это неопределенное поведение, поскольку временный объект Bar будет уничтожен при ;.

Foo Bar::Copy()
{
    return Bar();
}

безопаснее.НО благодаря @Cat Plus Plus и @celtschk я понял, что этот метод приводит к нарезке, теряя всю Bar специфическую информацию.Чтобы сохранить Bar объект Copy(), необходимо вернуть либо ссылку, либо указатель на объект.Здесь мы снова в начале, так как это UB.Таким образом, Bar должен выделяться динамически, чтобы его ссылка / указатель находилась в функции вне Copy().Кто должен нести ответственность за удаление этого динамически сгенерированного объекта Bar?

#include <memory>
std::shared_ptr<Foo> Bar::Copy()
{
    return std::shared_ptr(new Bar());
}

shared_ptr сделает это автоматически для вас.

...