Как правильно обрабатывать возврат по значению объектов с указателями?

Предположим, у меня есть класс 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? для дальнейших деталей.

Другие вопросы по тегам