Как правильно обрабатывать возврат по значению объектов с указателями?
Предположим, у меня есть класс Foo
которая "имеет" единственную переменную-член, которая является указателем на некоторый другой объект Bla
:
struct Foo {
Bla *bla;
Foo() {
this->bla = new Bla();
}
~Foo() {
delete this->bla;
}
};
Как мне обработать возврат по значению таких объектов?
Foo make_foo() {
return Foo();
}
Это создает новый Foo
а также Bar
, возвращает копию созданного Foo
объект включает в себя копию внутреннего указателя, а затем разрушает локальный объект и вместе с ним Bla
объект. Таким образом, следующий код не работает:
Foo f = make_foo();
std::cout << f.bla << std::endl;
Это вообще считается плохим дизайном в наши дни?
Должен ли я предоставить конструктор копирования? В этом случае глубокое копирование более сложных деревьев объектов может серьезно повлиять на производительность.
Должен ли я предоставить конструктор перемещения? Будет ли это обрабатывать bla
указатель правильно?
1 ответ
Поскольку ваш класс выделяет динамическую память и освобождает память в деструкторе, следуйте Правилу Трех. Предоставьте конструктор копирования и оператор копирования.
Если вы понимаете семантику перемещения или намереваетесь использовать rvalue ссылки, предоставьте конструктор перемещения и оператор присваивания перемещения. Видите, Правило Три становится Правилом Пяти с C++11? для дальнейших деталей.