如何正確理解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?
※嵌入式這行業是不是不行了?