標籤:

如何正確理解boost::any的設計?

class myclass
{
public:

myclass()
{
s = new string("11111111");
}

float f = 1.94323;

string* s;

~myclass()
{
delete s;
}

};

int main() {

{
myclass ms;

boost::any a1(ms);

}

system("Pause");

return 0;

}

這個段代碼會出錯,我知道是因為any和myclass中的指針指向同一塊內存,重複刪除了...

那麼是myclass類設計有問題,還是any設計有問題呢?

應該用怎麼樣的姿勢正確使用boost::any呢?


這件事情和any完全沒有關係,即便沒有any,也非常容易讓你的類掛掉。只需要:

myclass c0;
myclass c1(c0);

或者

myclass c0;
myclass c1;
c0 = c1;

原因就在於,你有默認構造,卻沒有拷貝構造和operator=。(C++11的話還有移動構造和移動的operator=)。這幾個往往是同時出現的,寫了一個就要考慮是不是應該寫其他幾個。

詳見Effective C++第二章。


你需要給你的myclass添加複製構造函數:

myclass(const myclass m)
: s{new string(*m.s)}
{
}

myclass(myclass m)
: s{m.s}
{
m.s = nullptr;
}


boost::any a1(ms);

這句話會調用myclass類的默認拷貝構造函數,生成對象ms的完全相同的副本傳遞給boost::any,然後這個副本析構後會把ms對象申請的那段內存釋放了。這樣當ms對象析構時會導致同一段內存被兩次釋放。

題主需要自己定義一個拷貝構造函數,類成員要深拷貝,避免上文提到的釋放同一段內存被兩次釋放的問題。具體請參見輪子哥
@vczh 的答案中的兩個寫法(拷貝構造和移動構造)


rule of three

rule of five?


推薦閱讀:

CUDA中可以用什麼來替代Vector類?
C++基本的知識都有了,但是很少C++解決問題,怎麼提高自己的實踐能力?
此處的C++斐波那契數列是如何實現的?
muduo::StringPiece?
嵌入式這行業是不是不行了?

TAG:C | BoostC庫 |