我認爲這是一個簡單的問題,但我一直在盯着一些複雜的遺留代碼,我不能再看到森林的樹木。這些應用程序將運行幾天,然後退出時失敗(當然,它不會讓更短的工作!)我懷疑SEGV。持有對同一對象的const引用的對象。退出時會發生什麼?
我簡化了下面的一些僞代碼的情況(希望我已經明白了)。
在人類方面:我有一個XYZ類,它有很多東西,包括一個指向簡單類ABC的向量(讓我們假設它很簡單)。這些指針在XYZ的析構函數中被刪除;這是所有的析構函數。
然後我有一個簡單的基類TheBase,它只有兩個簡單的虛擬方法,沒有析構函數。
最後,我有三個類,Tom和Dick(從TheBase派生)和Harry(不是從TheBase派生而來)。它們三個都是從一個const引用構造成一個XYZ對象;所以他們有一個對XYZ對象的const引用。他們也沒有析構函數。
在main中,boost :: shared_ptr是爲Tom,Dick和Harry對象中的每一個定義的。然後創建一個XYZ對象。接下來,將XYZ對象作爲常量引用傳遞給Tom,Dick和Harry對象。之後,發生了一大堆事情,主要退出。
那麼當所有這些東西超出範圍時會發生什麼?特別是XYZ對象?這會被正確處理嗎?似乎某些內容會被刪除多次。當 最後shared_ptr
指向它們被破壞由shared_ptr
管理
// A simple class (let's assume it is!)
class ABC
{
// unimportant stuff.
}
// class XYZ has an array of ABC objects. All the destructor does is delete those objects.
class XZY
{
public:
XYZ(vector<string> v1,
vector<string> v2,
vector<string> v3);
virtual ~XYZ(){
for (i = 0; i < n, i++){
delete my_abcs[i];
}
}
private:
vector <ABC*> my_abcs
// lots of other methods & members
}
// Simple base class with only 2 simple virtual methods
class TheBase
{
public:
virtual void minor_func1();
virtual void minor_func2();
}
// A class derived from base class. Constructs with a const reference to an XYZ class.
class Tom:TheBase
{
public:
Tom(const XYZ & xyz)
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Tom::Tom(const XYZ & xyz):my_xyz(xyz){
...
}
// Another class derived from base class. Constructs with a const reference to an XYZ class.
class Dick:TheBase
{
public:
Dick(const XYZ & xyz)
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Dick::Dick(const XYZ & xyz):my_xyz(xyz){
...
}
// A class NOT derived from base class but still constructs with a const reference to an XYZ class.
class Harry:TheBase
{
public:
Harry(const XYZ & xyz)
private:
const XYZ & my_xyz;
// lots of other methods & members
}
Harry::Harry(const XYZ & xyz):my_xyz(xyz){
...
}
main (...){
...
boost::shared_ptr <Tom> a_tom;
boost::shared_ptr <Dick> a_dick;
boost::shared_ptr <Harry> a_harry;
...
XYZ a_xyz(...);
a_tom.reset(new Tom(a_xyz));
a_dick.reset(new Dick(a_xyz));
a_harry.reset(new harry(a_xyz));
...
}
@Po你的意思是'vector',而不是'vector '。如果'ABC'是一個帶有值語義的簡單對象,它支持複製,這當然是更好的解決方案。 –
2013-03-26 17:35:19
另外,'TheBase'的析構函數可能應該是虛擬的。 (在代碼中給出,它不是必要的,但在一般情況下,如果基類有虛函數,它似乎是合理的指望有人試圖通過指針刪除派生類對象的基礎。) – 2013-03-26 17:36:44
@JamesKanze啊,謝謝 - 我沒有閱讀那裏的指針。儘管如此,我還是認爲向量被設計爲處理指針......此外,爲了以防萬一,最好使用虛擬析構函數。 – Polar 2013-03-26 17:36:58