C++中的析构函数和继承?

7
我使用Borland C++ Builder。
我遇到了问题。
#include <Classes.hpp>
class TMyObject : public TObject
{
   __fastcall TMyObject();
   __fastcall ~TMyObject();//I would like to inherite my destructor from TObject
};

__fastcall TMyObject::TMyObject() : TObject()//it will inherited my constructor from TObject
{
}

那么对于将继承~TObject的新析构函数呢?

__fastcall TMyObject::~TMyObject?????????????
4个回答

4

当你的对象寿命结束时,编译器会自动调用基类的析构函数。你不需要明确调用它。

TMyObject::TMyObject() : TObject()

不继承构造函数。
它被称为成员初始化列表,它使用特定的值初始化基类对象。

当您创建对象时。

TMyObject obj;

构造函数将按顺序调用:
constructor of TObject
constructor of TMyObject 

对象生命周期结束时,析构函数将按顺序调用:

destructor of TMyObject 
destructr of TObject

编译器会自动为您执行此操作,不需要显式调用它。

我想要这样的东西: - user558126
@user558126:恐怕这是不可能的。 - Alok Save
不,这是不可能的。无论如何,您都不必显式调用TObject的析构函数,因为这里没有放置新内容。但是,通过在TObject()级别使用虚拟,您提到的执行TMyObject()后跟执行~TObject()的操作会自动完成。 - Shlublu

4

这个问题可以在TObject的层面上解决。它的析构函数必须是虚拟的:

#include <Classes.hpp>
class TObject 
{
   __fastcall TObject();
   virtual __fastcall ~TObject(); 
};

这样你可以选择以下两种方式:

TObject * pobj = new TMyObject();
delete pobj;

或者

TMyObject * pobj = new TMyObject();
delete pobj;

两个析构函数都会被调用(先是~TMyObject(),然后是~TObject()),这样就不会有内存泄漏。


TObject 是 Borland 提供的系统类,它确实有一个虚析构函数。 - Remy Lebeau
好的!所以这里不应该有任何问题: ~TMyObject() 和 ~TObject() 应该在我们不需要做任何特定操作的情况下被调用。 - Shlublu
那这个问题最终没有任何依据了吗? - Shlublu
是的。原始的代码片段将按原样正常工作。当对象被释放时,会自动调用~TMyObject(),编译器会在~TMyObject()结束时处理调用~TObject() - Remy Lebeau
我同意Remy的观点,但我认为~TMyObject()应该是虚函数。 - Sam

1
如果你通过一个类型为TMyObject的引用销毁了TMyObject,那么你什么都不需要做。但是如果你有一个类型为TObject的指针/引用指向一个TMyObject,那么事情就会出错。 只有TObject的析构函数会被调用,而不会调用TMyObject的析构函数。
TObject* p = new TMyObject;
delete p; // Only the TObject::~TObject is called, not TMyObject::~TMyObject.

为了将对析构函数的调用决定推迟到运行时,您需要在 TObject 中将析构函数指定为 virtual。每当您有一个预期要派生的类时,析构函数都应该是虚拟的。否则,在未正确调用派生类析构函数时,总会存在资源泄漏的风险。

1
你感到困惑的原因是你可以像下面的例子一样明确指定要使用基类的哪个构造函数,但你不需要指定析构函数。
TMyObject::TMyObject() : TObject()

您可以通过编写 TObject (int i) 等不同的构造函数来使用它。

TMyObject::TMyObject() : TObject (3)

一个对象只能以一种方式拆除,但可以通过具有不同构造函数的方式构造多种方式。
简而言之,在派生类析构函数中不需要提及基类析构函数的名称。当你销毁派生对象(例如,通过执行delete derivedObj),它会自动首先调用派生类析构函数,然后再调用基类析构函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接