浅谈C++对象的内存分布和虚函数表

 更新时间:2016年12月25日 11:10:15   投稿:jingxian  
下面小编就为大家带来一篇浅谈C++对象的内存分布和虚函数表。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数。

1、非静态数据成员被放在每一个对象体内作为对象专有的数据成员。

2、静态数据成员被提取出来放在程序的静态数据区内,为该类所有对象共享,因此只存在一份。

3、静态和非静态成员函数最终都被提取出来放在程序的代码段中并为该类所有对象共享,因此每一个成员函数也只能存在一份代码实体。在c++中类的成员函数都是保存在静态存储区中的 ,那静态函数也是保存在静态存储区中的,他们都是在类中保存同一个惫份。

因此,构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针。成员函数为该类所有对象共享,不仅是处于简化语言实现、节省存储的目的,而且是为了使同类对象有一致的行为。同类对象的行为虽然一致,但是操作不同的数据成员。

#include"iostream.h"
class A
{


private:
 int x;
 int y;


public:
 void sety()
 {
 y=5;
 }
 void print()
 {
 cout<<"x="<<x<<endl<<"y="<<y<<endl;
 }
};

void main()
{
 A a;
 a.sety();
 a.print();
 int *p=(int *)&a;//对象a的内存模型里面,只有非静态数据成员,所以是合理的。
 *p=6;
 a.print();
}

4、单继承的对象的内存布局,第一个为虚函数表指针vtbl,其后为成员且先基类后子类,虚函数表里包含了所有的虚函数的地址,以NULL结束。虚函数如果子类有重写,就由子类的重新的代替。

 <一> 上述类图的解释:B的v2覆盖了A的v2,C的v1覆盖了A的v1,C的v3覆盖了B的v3.

注意:发生覆盖的特征有:

1) 不同的范围(分别位于派生类与基类);

2) 函数名字相同;

3) 参数相同;

4) 基类函数必须有virtual关键字。

成员函数被重载的特征
 
(1)相同的范围(在同一个类中);
 
(2)函数名字相同;
 
(3)参数不同;
 
(4)virtual 关键字可有可无。

 
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下
 
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
 
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)  

<二> 类C的对象的内存模型为:

单继承的对象的布局,第一个为虚函数表指针vtbl,其后为成员且先基类后子类,虚函数表里包含了所有的虚函数的地址,以NULL结束。虚函数如果子类有重写,就由子类的重新的代替。

5、与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数替换父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面。

<一> 对类图的解释:D的v3覆盖了B3的v3,另外D有一个新的虚函数vD。

<二> class D 的内存模型

总结:与单继承相同的是所有的虚函数都包含在虚函数表中,所不同的多重继承有多个虚函数表,当子类对父类的虚函数有重写时,子类的函数覆盖父类的函数在对应的虚函数位置,当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面

6. 虚继承,使公共的基类在子类中只有一份,我们看到虚继承在多重继承的基础上多了vbtable来存储到公共基类的偏移。

<一>类图的解释:D2覆盖了B的vB,GD覆盖了D1的vD1同时也覆盖B的vB,GD也有自己的虚函数vGD。

<二> class GD的内存模型

总结:虚继承,使公共的基类在子类中只有一份,我们看到虚继承在多重继承的基础上多了vbtable来存储到公共基类的偏移

以上就是小编为大家带来的浅谈C++对象的内存分布和虚函数表全部内容了,希望大家多多支持脚本之家~

相关文章

  • C语言的基本编写规范你了解吗

    C语言的基本编写规范你了解吗

    这篇文章主要为大家介绍了C语言的基本编写规范,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • Qt使用随机验证码的实现示例

    Qt使用随机验证码的实现示例

    有时候在登录界面需要验证码功能,这样能够防止被恶意程序攻击,本文主要介绍了Qt使用随机验证码的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • C/C++中数据类型转换详解及其作用介绍

    C/C++中数据类型转换详解及其作用介绍

    这篇文章主要介绍了C/C++中数据类型转换详解及其作用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • C语言SetConsoleCursorInfo函数使用方法

    C语言SetConsoleCursorInfo函数使用方法

    这篇文章介绍了C语言SetConsoleCursorInfo函数的使用方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • 基于C++编写一个文章生成器

    基于C++编写一个文章生成器

    这篇文章主要为大家介绍一个有趣的小程序,就是利用C++编写一个文章生成器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-03-03
  • 浅析内存对齐与ANSI C中struct型数据的内存布局

    浅析内存对齐与ANSI C中struct型数据的内存布局

    当在C中定义了一个结构类型时,它的大小是否等于各字段(field)大小之和?编译器将如何在内存中放置这些字段?ANSI C对结构体的内存布局有什么要求?而我们的程序又能否依赖这种布局
    2013-09-09
  • 带你深度走入C语言取整以及4种函数

    带你深度走入C语言取整以及4种函数

    大家都知道取整这回事,但是对于取整只有单一的认识,下面这篇文章主要给大家介绍了关于C语言取整以及4种函数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • C++实现简单贪吃蛇游戏

    C++实现简单贪吃蛇游戏

    这篇文章主要为大家详细介绍了C++实现简单贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • c语言全盘搜索指定文件的实例代码

    c语言全盘搜索指定文件的实例代码

    c语言全盘搜索指定文件的实例代码,需要的朋友可以参考一下
    2013-03-03
  • C++超详细讲解函数对象

    C++超详细讲解函数对象

    在c++中,我们把所有能当作函数使用的对象统称为函数对象。它是实现operator()的任何类型,此运算符被称为调用运算符,当调用此操 作符时,其表现形式如同普通函数调用一般,因此取名叫函数对象
    2022-06-06

最新评论