我认为这是一个简单的问题,但我一直在盯着一些复杂的遗留代码,我不能再看到森林的树木。这些应用程序将运行几天,然后退出时失败(当然,它不会让更短的工作!)我怀疑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