2

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?

Jens
  • 6,642
  • 6
  • 45
  • 64
  • Why do you think the code fails? `bla` is also copied (the pointer itself). You might want to see [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – songyuanyao Sep 19 '16 at 02:17
  • 1
    If appropriate, there is also [copy-on-write](http://stackoverflow.com/questions/628938/what-is-copy-on-write) for your copy constructor, which may mitigate your performance impacts. Share some reference counted copies of `bla` (e.g. use a [`shared_ptr`](http://en.cppreference.com/w/cpp/memory/shared_ptr)), then don't make a deep copy until you actually need to modify the data. – Jason C Sep 19 '16 at 02:24

1 Answers1

2

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.

Community
  • 1
  • 1
R Sahu
  • 196,807
  • 13
  • 136
  • 247