我认为这是一个简单的问题,但我一直在盯着一些复杂的遗留代码,我再也看不到森林的树木了。该应用程序将运行数天,然后在退出时失败(当然对于较短的工作它不会失败!)我怀疑是 SEGV。
我用下面的一些伪代码简化了这个案例(希望我做对了)。
用人类的话来说:我有一个类 XYZ,它有很多东西,包括一个指向简单类 ABC 的指针向量(假设它很简单)。这些指针在 XYZ 的析构函数中被删除;这就是析构函数所做的一切。
然后我有一个简单的基类 TheBase,它只有两个简单的虚拟方法,没有析构函数。
最后,我有三个类,Tom 和 Dick(从 TheBase 派生)和 Harry(不是从 TheBase 派生的)。这三个类都是从对 XYZ 对象的 const 引用构造的;所以他们有一个对 XYZ 对象的 const 引用。它们也没有析构函数。
总的来说, boost::shared_ptr 是为 Tom、Dick 和 Harry 对象中的每一个定义的。然后创建一个 XYZ 对象。接下来,XYZ 对象作为对 Tom、Dick 和 Harry 对象的 const 引用传递。在那之后,发生了一大堆事情并且主要退出。
那么当所有这些事情都超出范围时会发生什么?特别是 XYZ 对象?这会被正确处理吗?似乎某些内容将被多次删除。
// 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) );
...
}