虚函数——虚表总结-创新互联


非虚拟继承

成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于成都网站设计、做网站、成都外贸网站建设公司、新民网络推广、微信小程序定制开发、新民网络营销、新民企业策划、新民品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们大的嘉奖;成都创新互联公司为所有大学生创业者提供新民建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com

【带虚函数的类】

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<

}

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<

}

int _data1;

};

int main()

{

Base b;

b._data1 = 0x01;

return 0;

}

Base类没有显式定义自己的构造函数,此时编译器会和成默认的构造函数,

虚函数——虚表总结

合成的构造函数中主要完成在对象头4个字节中填写虚表地址:

虚函数——虚表总结

Base类对象最后的模型如下:

虚函数——虚表总结

注意:同一个类的对象共用同一个虚表

虚函数——虚表总结

从上述的结果中可以得到印证。

【单继承(派生类中没有虚函数覆盖)】

class Base

{

public:

virtual void FunTest1()

{cout<<"Base::FunTest1()"<

virtual void FunTest2()

{cout<<"Base::FunTest2()"<

          int _data1;

};

class Derive:public Base

{

public:

virtual void FunTest3()

{cout<<"Derive::FunTest3()"<

virtual void FunTest4()

{cout<<"Derive::FunTest4()"<

int _data2;

};

// 打印虚表

typedef void (*VtbFun)();

void PrintVtable()

{

cout<<"Derive类的虚函数表:"<

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

int* pVTable = (int*)*(int*)&d1;

VtbFun FunTest = (VtbFun)*pVTable;

while(NULL != FunTest)

{

FunTest();

cout<<(int*)FunTest<

pVTable += 1;

FunTest = (VtbFun)*pVTable;

}

cout<<"虚表结束:"<

}

int main()

{

Base b1;

Derive d1;

return 0;

}

按照如上分析的顺序,探索下单继承下派生类对象模型以及虚表

首先看看编译器为派生类合成的缺省构造函数:

虚函数——虚表总结

派生类构造函数中进行了如下事情:

虚函数——虚表总结

Derive d1;

d1._data1 = 0x01;

d1._data2 = 0x02;

派生类最后的对象模型为:

虚函数——虚表总结

【单继承(派生类中有虚函数覆盖)】

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<

}

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<

}

int _data1;

};

class Derive:public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<

}

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<

}

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<

}

int _data2;

};

int main()

{

PrintVtable();

return 0;

}

派生类对象模型及虚表建议规则:

虚函数——虚表总结

【多继承(派生类不覆盖基类虚函数)】

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<

}

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<

}

int _data1;

};

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<

}

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<

}

int _data2;

};

class Derive:public Base, public Base1

{

public:

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<

}

int _data3;

};

int main()

{

cout<<"sizeof(Derive) = "<

Derive d;

d._data1 = 0x01;

d._data2 = 0x02;

d._data3 = 0x03;

PrintVtable();

return 0;

}

同样:看看编译器合成的派生类的对象做了什么工作

虚函数——虚表总结

观察下派生类的对象模型和虚表的建立过程

虚函数——虚表总结

从上面的结果可以看出,Derive类自己特有的虚函数直接添加在Base类对应虚函数表最后的位置,大家可将Base和Base1的顺序交换验证下。

【多继承(派生类覆盖基类虚函数)】

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<

}

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<

}

int _data1;

};

class Base1

{

public:

virtual void FunTest3()

{

cout<<"Base1::FunTest3()"<

}

virtual void FunTest4()

{

cout<<"Base1::FunTest4()"<

}

int _data2;

};

// 这次将继承列表中Base和Base1的位置互换

class Derive:public Base1, public Base

{

public:

virtual void FunTest1()

{

cout<<"Derive::FunTest1()"<

}

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<

}

virtual void FunTest5()

{

cout<<"Derive::FunTest5()"<

}

int _data3;

};

int main()

{

          PrintVtable();

return 0;

}

此时派生类的对象模型和虚表的结构:

虚函数——虚表总结

虚拟继承

// 没有虚函数覆盖,但派生类有自己的虚函数

class Base

{

public:

virtual void FunTest1()

{

cout<<"Base::FunTest1()"<

}

virtual void FunTest2()

{

cout<<"Base::FunTest2()"<

}

int _data1;

};

class Derive:virtual public Base

{

public:

virtual void FunTest3()

{

cout<<"Derive::FunTest3()"<

}

virtual void FunTest4()

{

cout<<"Derive::FunTest4()"<

}

int _data2;

};

虚拟继承编译器为派生类合成的默认构造函数分析

虚函数——虚表总结

编译器为派生类合成的默认构造函数任务分析:

虚函数——虚表总结虚函数——虚表总结

虚拟继承派生类对象模型分析

虚函数——虚表总结

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


分享标题:虚函数——虚表总结-创新互联
转载注明:http://pwwzsj.com/article/dejceh.html