c++copy-constructormove-semanticsreturn-by-value

How to handle return-by-value of objects with pointers correctly?


Suppose I have a class Foo which "has a" single member variable that is a pointer to some other object of Bla:

struct Foo {
    Bla *bla;

    Foo() {
        this->bla = new Bla();
    }
    ~Foo() {
        delete this->bla;
    }
};

How do I handle return-by-value of such objects?

Foo make_foo() {
    return Foo();
}

This creates a new Foo and Bar, returns a copy of the created Foo object including a copy of the internal pointer, and then destructs the local object and with it the Bla object. Thus, the following code fails:

Foo f = make_foo();
std::cout << f.bla << std::endl;

Is this generally considered poor design these days?

Should I provide a copy constructor? In that case, deep-copying more complex object trees can have severe performance impacts.

Should I provide a move constructor? Would that handle the bla pointer correctly?


Solution

  • Since your class allocates dynamic memory and deallocates the memory in the destructor, follow The Rule of Three. Provide a copy constructor and copy assignment operator.

    If you understand move semantics or intend to use rvalue references, provide a move constructor and move assignment operator as well. See Rule-of-Three becomes Rule-of-Five with C++11? for further details.