2016-09-19 135 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