2016-09-19 132 views
2

假设我有一类Foo其中“有一个”单一成员变量是一个指向Bla其他对象:如何正确使用指针处理对象的返回值?

struct Foo { 
    Bla *bla; 

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

如何处理回传值这样的对象?

Foo make_foo() { 
    return Foo(); 
} 

这将创建一个新的FooBar,返回复制创建Foo对象包括内部指针的副本,然后自毁本地对象,并用它来Bla对象。因此,下面的代码将失败:

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

这些通常被认为是糟糕的设计吗?

我应该提供copy constructor吗?在这种情况下,深度复制更复杂的对象树会对性能造成严重影响。

我应该提供一个move constructor吗?那会正确处理bla指针吗?

+0

为什么你认为代码失败? 'bla'也被复制(指针本身)。你可能想看看[三条法则是什么?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree)。 – songyuanyao

+1

如果合适,还有复制构造函数的[copy-on-write](http://stackoverflow.com/questions/628938/what-is-copy-on-write),这可能会减轻对性能的影响。分享一些引用计数的'bla'副本(例如,使用['shared_ptr'](http://en.cppreference.com/w/cpp/memory/shared_ptr)),然后不要进行深层复制,直到你真的需要修改数据。 –

回答

2

由于您的类分配动态内存并释放析构函数中的内存,因此请按照The Rule of Three。提供一个拷贝构造函数和拷贝赋值操作符。

如果您了解移动语义或打算使用右值引用,请提供移动构造函数和移动赋值运算符。有关更多详细信息,请参阅Rule-of-Three becomes Rule-of-Five with C++11?

+0

很好的参考*三规则*,谢谢! – Jens