C++多重继承

今天在考虑一个C++实现的时候需要用到多重继承,突然发觉这么多年来基本都没怎么用过多重继承C++多重继承

只是了解多重继承可以用,不过很容易出问题,尤其是基类是从相同的类派生出来的。

今天我需要用到的没有这么麻烦,不过我还是对于多重继承的内存释放感到困惑。

大家应该都知道设计C++类的时候,如果这个类需要被继承,建议把析构函数声明为virtual的。

之前对于这一点的理解是:

基类成员的内存释放一般是在基类析构函数里面完成的,如果基类析构函数不是虚函数,派生类析构的时候不会调用基类的,就会导致内存泄露。

下面是随手写的一个多重继承测试用例

classInterface1

{

public:

~Interface1()

{

printf(
"~Interface1\n");

};

virtualvoidFunc1()=0;

protected:

intmData1;

};



classInterface2

{

public:

~Interface2()

{

printf(
"~Interface2\n");

};

virtualvoidFunc2()=0;

protected:

intmData2;

};



classBase

{

public:

~Base()

{

printf(
"~Base\n");

};

voidFunc3()

{

printf(
"Func3\n");

}

protected:

intmData;

};



classDerived :publicBase,publicInterface1,publicInterface2

{

public:

~Derived()

{

printf(
"~Derived\n");

};

voidFunc1()

{

printf(
"Func1\n");

}



voidFunc2()

{

printf(
"Func2\n");

}

};



////////////////////////////////////////////

//Test case

////////////////////////////////////////////

Derivedd=newDerived();

Base
b=d;

Interface1
i1=d;

Interface2
i2=d;

i1
->Func1();

i2
->Func2();

b
->Func3();

delete i2;

问题来了,delete i2;这一行会导致Assert(Debug版)

这是为什么呢?

先让我们在watch window里面看看这些变量

i10x004e99c0Interface1

i2
0x004e99c8Interface2


b
0x004e99d0Base

d
0x004e99c0Derived

Wow,地址竟然都不一样,想想也对,因为虚表的原因。具体的可以参考:这里

当我把所有析构函数改成virtual的以后,delete就没有问题了。

这中间发生了什么事情呢?因为i2的地址和我们分配的地址明显是不一样,直接free这块内存的话,当然会出错

查看正确的析构代码的汇编代码发现窍门在这里

i2的Interface2虚表中的析构函数指向了下面这个地址
[thunk]:Derived::vector deleting destructor</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">:<br></br>004117D0 sub ecx,10h<br></br>004117D3 jmp Interface2::scalar deleting destructor'(4113C5h)



==>

004113C5jmpDerived::`scalar deleting destructor'(411860h)

注意sub ecx, 10h,经过这个变幻以后得到的地址就是我们前面真正的内存地址。

也就是说在每个基类的虚表中指向的析构函数其实并不是Derived的析构函数地址,而是一个编译器自动生成的中间代码地址,这段代码的功能就是把这个基类的实例内存地址(this指针)转换成内存分配时的真正地址(也就是当时实例化的类型),然后再调用实际类型的析构函数(Derived::~Derived())。
原文链接: https://www.cnblogs.com/hyamw/archive/2010/11/07/1871266.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17063

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午5:32
下一篇 2023年2月7日 下午5:34

相关推荐