C++和虚拟析构函数
我正在应用程序中编写一个实用程序类,其中它们可能是也可能不是未来的派生类。我没有任何虚拟函数(使用虚拟 dtor 的一般准则),因此考虑到我的内存限制,我选择在该实用程序类中不使用虚拟析构函数。
后来一些程序员 - 有人通过派生我的实用程序类来添加它。现在,如果在代码中的任何位置,我的新类在 new'd 中并被删除,则不会调用正确的 dtor,因为基类 dtor 未设为虚拟(请参阅示例代码)。
除了返回并更改基类之外 - 在这种情况下还有哪些解决方案?
#include <iostream>
using namespace std;
class utility {
int i, j;
public:
utility () { cout << "utility ctor\n";};
~utility () { cout << "utility dtor\n";};
void dosomething () { cout << "haha\n";};
};
class addtoutility: public utility {
char *ch;
public:
addtoutility () { ch= new char(); cout << "added ctor\n";};
~addtoutility () { delete ch; cout << "added dtor\n";};
void andnowaddsomefunctionality () {};
};
int main () {
utility *u = new addtoutility();
//lots of interesthing code
delete u;
}
I am writing a utility class in an application in which they may or may not be future derivations. I dont have any virtual functions (the general guideline for using virtual dtors), and so given my memory restrictions I choose not to have a virtual destructor in this utility class.
A few programmers later - someone adds to my utility class by deriving from it. Now if, anywhere in the code my new class in new'd and deleted the correct dtor will not be called as the base class dtor was not made virtual (see example code).
Other than going back and changing the base class - what solutions are there in this case?
#include <iostream>
using namespace std;
class utility {
int i, j;
public:
utility () { cout << "utility ctor\n";};
~utility () { cout << "utility dtor\n";};
void dosomething () { cout << "haha\n";};
};
class addtoutility: public utility {
char *ch;
public:
addtoutility () { ch= new char(); cout << "added ctor\n";};
~addtoutility () { delete ch; cout << "added dtor\n";};
void andnowaddsomefunctionality () {};
};
int main () {
utility *u = new addtoutility();
//lots of interesthing code
delete u;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的基类不是多态的,因此在任何情况下拥有指向基类的指针都没有什么价值。您的基类通过不在任何地方使用
virtual
关键字来证明它不是多态的。如果有人想将它用作多态层次结构的基类,那么他们可以向从其派生的第一个类添加一个虚拟析构函数,并在必要时保存指向该基类类型的指针。
你无法阻止后来的程序员挖掘自己的陷阱,但非多态类没有任何问题,你不需要对它做任何事情来“使其安全”。
作为这种常见且可接受的做法的证据,您只需查看标准库即可。有许多类(严格来说,其中大多数是类模板)没有虚函数和虚析构函数。
Your base class is not polymorphic so there is little value to having a pointer-to-base in any case. Your base class documents the fact that it is not polymorphic by not using the
virtual
keyword anywhere.If someone wants to use it as the base class to a polymorhpic hierarchy then they can add a
virtual
destructor to the first class they derive from it and, where necessary, hold pointers to that base class type.You can't prevent programmers who come later from digging their own traps but there is nothing wrong with a non-polymorhphic class and you don't need to do anything to it to "make it safe".
As evidence that this is common and acceptable practice, you need only take a look at the standard library. There are many classes (strictly, the majority of them are class templates) with no virtual functions and no virtual destructor.
工作:
Works:
如果根本无法修改基类的代码,可以在派生类中添加像Destroy()这样的函数。有点烦人,但如果您想到像 Brush 这样的 Win32 对象,我们一直都会这样做。
If you can't modify the code of the base class at all, you can add a function to the derived class like Destroy(). Kind of annoying but we do it all the time if you think of Win32 objects like Brush.