class BaseTest {
protected:
virtual void finalizeParts() {
delete m_part;
};
public:
int* m_part;
BaseTest() {
m_part = new int;
}
void finalize() {
finalizeParts();
delete this;
}
};
class SubTest : public BaseTest {
protected:
void finalizeParts() {
BaseTest::finalizeParts();
delete m_anotherPart;
}
public:
int* m_anotherPart;
SubTest() {
m_anotherPart = new int;
}
};
SubTest* test = new SubTest();
test->finalize();
我在我的类的析构函数中避免虚函数调用时遇到了麻烦(我讨厌C ++强迫我首先执行此操作)。与基类中的常见清理策略相比,覆盖所有子类中的析构函数似乎非常不方便,使用一些可以在需要时覆盖的虚函数。作为一种解决方法,我正在考虑引入一个“最终确定”的方法。函数在我的基类中执行清理,最后调用'删除这个'。这可能是一个非常不寻常的解决方案,所以我想知道我是否以错误的方式接近这个问题,以及是否有一个更明显的方式来写“正确”的方法。 C ++中的析构函数。
答案 0 :(得分:1)
如果您的对象聚合了管理其资源的其他对象(例如,考虑智能指针。一般原则称为RAII),那么根本不需要析构函数。
当然,你仍然需要每个这样的“经理”的解决方案,但由于需要关注的信息和资源较少,它应该更容易实现。
在你的情况下自我删除似乎是不好的方法,因为没有人会期望finalize
释放对象的记忆(最不惊讶的原则)。虽然内部实现可能没问题(例如,我曾经在实现shared_ptr时做过delete this
。也就是说,当资源管理器的计数器达到0时我就做了。但是这种行为无论如何都没有暴露给最终用户)
答案 1 :(得分:1)
你的做法是错误的。
使用虚拟析构函数,将调用基类的析构函数以及派生类的析构函数 - 因此您应该为每个派生类实现析构函数,这将只删除派生类的相关部分,并让基类的析构函数清除基类。
如果你有一个派生类链,那么将调用每个继承级别的析构函数 - 从大多数派生类到基类的顺序。
对于您的示例,所需要的只是:
class BaseTest {
public:
virtual ~BaseTest () {
delete m_part;
};
int* m_part;
BaseTest() {
m_part = new int;
}
};
class SubTest : public BaseTest {
public:
virtual ~SubTest () {
//~BaseTest() will be called automatically
delete m_anotherPart;
}
int* m_anotherPart;
SubTest() {
m_anotherPart = new int;
}
};
SubTest* test = new SubTest();
delete test;
答案 2 :(得分:0)
这对你来说更简单吗?
class BaseTest {
public:
std::unique_ptr<int> m_part;
BaseTest() : m_part(new int) {}
virtual ~BaseTest() {}
};
class SubTest : public BaseTest {
public:
std::unique_ptr<int> m_anotherPart;
SubTest() : m_anotherPart(new int) {}
};
SubTest test;
或者就此而言,
class BaseTest {
public:
int m_part;
};
class SubTest : public BaseTest {
public:
int m_anotherPart;
};
SubTest test;
我认为你有XY problem。而不是向我们询问你已经做过的奇怪的重新实现 - 已经做了什么,请询问你在析构函数中调用虚函数时遇到的问题。