简体   繁体   English

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

[英]Destructors and inheritance in C++?

I use Borland C++ Builder. 我使用Borland C ++ Builder。

And i had o problem 我有问题

#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
{
}

And for that new destructor that will inherite ~TObject ? 对于那个将继承~TObject新析构函数?

__fastcall TMyObject::~TMyObject?????????????

Destructor of the Base class will be automatically called by the compiler, when your objet life time ends. 当您的对象生命周期结束时,编译器将自动调用Base类的析构函数。 you do not need to call it explicitly. 你不需要明确地调用它。

TMyObject::TMyObject() : TObject()

Does not inherit the constructor. 不继承构造函数。
It is called as Member initializer list and it initializes the Base class object with a particular value. 它被称为成员初始化列表 ,它使用特定值初始化Base类对象。

When you create the object. 创建对象时。

TMyObject obj;

The constructors will be called in order: 构造函数将按顺序调用:

constructor of TObject
constructor of TMyObject 

When the object life time ends the destructors will be called in the order: 当对象生命周期结束时,将按顺序调用析构函数:

destructor of TMyObject 
destructr of TObject

The compiler will do so for you, do not need to call it explicitly. 编译器会为您执行此操作,不需要显式调用它。

This can be solved at TObject 's level. 这可以在TObject的级别上解决。 Its destructor has to be virtual: 它的析构函数必须是虚拟的:

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

This way you can either do: 这样你可以这样做:

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

or 要么

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

Both destructors will be called ( ~TMyObject() first and then ~TObject() ) and you will have no leak. 两个析构函数都将被调用( ~TMyObject() ,然后是~TObject() ),你就没有泄漏。

If you destroy a TMyObject through a reference of type TMyObject you don't have to do anything. 如果通过TMyObject类型的引用销毁TMyObject ,则不必执行任何操作。 In case you have a pointer/reference of type TObject to a TMyObject things will go wrong. 如果你有一个TObject类型的指针/引用到TMyObject会出错。 Only the TObject destructor will be called, not the TMyObject one: 调用TObject析构函数,而不是TMyObject

TObject* p = new TMyObject;
delete p; // Only the TObject::~TObject is called, not TMyObject::~TMyObject.

To have the decision on what destructor to call deferred to runtime, you need to specify the destructor as virtual in TObject . 要决定要调用的析构函数延迟到运行时,需要在TObject中将析构函数指定为virtual Whenever you have a class that is intended to be derived from, the destructor should be virtual. 每当你有一个旨在派生的类时,析构函数应该是虚拟的。 Otherwise there is always a risk for resource leaks when the derived class destructor isn't called properly. 否则,在未正确调用派生类析构函数时,始终存在资源泄漏的风险。

What's causing the confusion to you is that you can specifically mention "which" constructor of the base class you want to use as in the following example. 导致混淆的是,您可以在下面的示例中特别提及要使用的基类的“哪个”构造函数。 But you can't/ don't need to specify the destructor. 但是你不能/不需要指定析构函数。

TMyObject::TMyObject() : TObject()

You could use a different constructor, say TObject (int i) by writing 你可以使用不同的构造函数,比如说TObject (int i)

TMyObject::TMyObject() : TObject (3)

An object can be destructed in only one way but it can be constructed in several ways (by having different constructors). 一个对象只能以一种方式被破坏,但它可以用几种方式构造(通过具有不同的构造函数)。

So, in short, you don't need to mention the name of the base class destructor in the derived class destructor. 因此,简而言之,您不需要在派生类析构函数中提及基类析构函数的名称。 As soon as you destroy the derived object (say, by doing delete derivedObj ), it will first call the derived class destructor and then base class destructor by itself. 一旦销毁派生对象(例如,通过delete derivedObj ),它将首先调用派生类析构函数,然后自行调用基类析构函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM