首页 > 编程知识 正文

c析构函数怎么写,举例说明虚析构函数的作用

时间:2023-05-04 03:10:17 阅读:27186 作者:4675

文章的目录结构析构函数和析构函数的调用顺序定义原因作用代码

析构函数和析构函数的调用顺序

构造函数调用顺序:

创建对象时,首先调用基类的构造函数,然后调用派生类的构造函数,依次类推,直到到达底层目标派生类的构造函数。

析构函数调用顺序:

删除对象时,首先调用其派生类的析构函数,然后调用顶级析构函数,依次类推直到到达顶级析构函数。

简单来说,构造函数是“从上到下”调用,而析构函数是“从下到上”调用。

构造函数的调用顺序是:调用基类的构造函数-调用成员对象的构造函数-调用自己的构造函数。 构造函数的调用顺序完全不受构造函数初始化列表表达式中的顺序影响,它与基类的声明次数和成员对象在函数中的声明顺序相关。 如果基类中有成员对象,则还会首先调用基类中的成员对象构造函数

# includeiostreamclassa { public : a (} { STD :3360 cout '结构A' std:endl; (a ) ) { std:cout )析构函数a ) STD3360:endl; }; classb { public : b (} { STD :3360 cout '结构B' std:endl; (b ) ) { std:cout )析构函数b ) STD3360:endl; } private: A a_; (; class c : publicb { public : c (} { STD :3360 cout '结构C' std:endl; (c ) ) { std:cout )析构函数c ) STD3360:endl; }; int main () ) bb; C; )结构a结构b结构a结构b结构c结构b结构a结构b结构b结构a定义如果不是C++类有继承时,析构函数必须为虚函数虚函数,在使用时可能存在内在泄漏问题。

在原因公开继承中,基类对派生类及其对象的操作只影响从基类继承的成员。 如果要处理基类中未继承的成员,请将基类中的此操作(函数)定义为虚函数。 析构函数也同样需要。

如果使用基类指针删除派生类中的对象,并且此基类中存在非虚析构函数,则结果为未定义。 结果,对象的派生部分不会被丢弃,但基类部分很可能被丢弃,这导致了“部分分析机制”的状况,这是内存泄漏。

实际上起着虚表的作用

虚表的详细说明

当使用基类指针删除派生类中的对象时,它的作用是调用派生类的析构函数。

当然,并不是所有类的析构函数都写为虚函数。 因为如果类具有虚函数,编译器会向类中添加虚函数表,并将虚函数指针存储在其中,从而增加类的存储空间。 因此,只有将类用作基类时,才能将析构函数写为虚函数。

总结一下虚析构函数的作用:

)1)如果父类的析构函数不加virtual关键字

如果父类析构函数未声明为虚拟析构函数,子类继承父类,父类指针指向子类,则delete将丢失父类指针,只移动父类析构函数,而子类指向子类

代码# includeiostreamclassa { public : a (} { STD :3360 cout '结构A' std:endl; (a ) ) { std:cout )析构函数a ) STD3360:endl; }; classb { public : b (} { STD :3360 cout '结构B' std:endl; (b ) ) { std:cout )析构函数b ) STD3360:endl; } private: A a_; (; class c : publicb { public : c (} { STD :3360 cout '结构C' std:endl; (c ) ) { std:cout )析构函数c ) STD3360:endl; }; int main () { B* c=new C ); delete c; }结构a结构b结构c结构b结构a直接调用基类析构函数,而不调用虚拟表,子类析构函数(2)如果父类的析构函数加virtual关键字

当父类析构函数被声明为虚拟析构函数时,如果子类继承父类,而父类指针指向子类,则delete会丢失父类指针,首先移动子类析构函数,然后移动父类析构函数

代码# includeiostreamclassa { public : a (} { STD :3360 cout '结构A' std:endl; (a ) ) { std:cout )析构函数a ) STD3360:endl; }; classb { public : b (} { STD :3360 cout '结构B' std:endl; } virtual ~B () { std:cout '析构函数B' std:endl; } private: A a_; (; class c : publicb { public : c (} { STD :3360 cout '结构C' std:endl; (c ) ) { std:cout )析构函数c ) STD3360:endl; }; int main () { B* c=new C ); delete c; }结构a (结构b )结构c (结构b )结构a )每个类都有一个虚拟表,在生成对象时自动将对象的虚拟指针指向类的虚拟表。 因为虚拟指针属于基类,所以基类可以访问子类的虚拟指针,所以当有delete基类指针时,可以通过虚拟表调用子类析构函数,并在重新解析父类析构函数时访问内存

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。