C++对象内存模型详解(基于GDB)

第1关:STL模板之queue实例一:最少个数 头歌自创答案 阅读详情

因为挺多内容的来自别人博客的学习,所以把相关博客的链接拉上:
虚函数解析:http://blog.csdn.net/haoel/article/details/1948051
C++ 对象的内存布局(上):http://blog.csdn.net/haoel/article/details/3081328
C++对象的内存布局(下):http://blog.csdn.net/haoel/article/details/3081385
在这篇博客里面,我们将致力于利用GDB工具来分析以下几种情况的对象内存模型:
1.对象的虚函数表是怎么回事?
2.对象的虚函数是怎么分布的?
3.函数继承的虚函数表是怎么样的?
4.子类复写了父类的函数的结果虚函数表会怎样构成?
5.有成员变量的情况应该怎么处理?

在开始之前,我想先说几个基本概念,这几个基本概念可以帮助我们快速理解对象的内存是如何分配的?
1.C++的函数对象构造过程是从基类开始构造,然后在构造子类。就像搭房子一样,先盖基底然后再盖上层建筑。那么,析构的顺序也是相同的,先调用子类的析构函数,然后再调用基类的析构函数,就跟拆房子先从上层开始拆。
2.我们为何要使用虚函数、虚类,虚继承的目的。从目的出发,我们使用虚函数的最大目的是为了多态,多态的目的就是基类给你指定函数的接口形式,然后子类再去overwrite,这就必然会涉及到函数的覆盖。覆盖的目的就是换一个新的函数地址,这就需要一个虚函数表的数据结构。那么,反过来说。如果不是虚函数,那么我们子类的目的就是可以使用基类的函数,这就不需要虚函数表这个数据结构,而是正常的在this指针里面指向的空间并且调用。
3.顺序问题:虚基类(虚继承)放在this指针指向的空间的最后部分。所以,我们想要访问共有的基类元素就可以经过访问虚基类指针访问虚基类表中的偏移量,通过偏移量来获得我们的基类共有元素。
4.本类的虚函数存储在第一个虚函数表的最后一个。
5.虚函数表的目的是为了重载,之前一直犯了个错误。认为对象的函数都需要一个函数指针来指向。但是实际上,类似C语言的函数声明一样,非虚函数都已经通过函数声明声明好了。

好了,有了这些元素,我们就可以进行分析了:
首先,我们先来分析最简单的例子,不考虑虚继承,但是有非虚函数:

class Vertex3d
{
public:
    void Foo(){printf("Vertex3d::Foo() called !\n");}
};


class MY:public Vertex3d
{
public:
    void print(){printf("Hello,world!!");}
};

int main()
{
    printf("%lu\n",sizeof(MY));
    return 0;
}

结果是1。
只有一个字节,可见对象里面的函数并不会占据空间。
其次,我们想再难一点,这个时候,我们讨论一下当虚函数加入其中的情况:

#include<iostream>
using namespace std;
class Base {
     public:
            virtual void f() { cout << "Base::f" << endl; }
            virtual void g() { cout << "Base::g" << endl; }
            virtual void h() { cout << "Base::h" << endl; }
};


class MY:public Base
{
public:
    void test(){}
};



int main()
{
    printf("%lu\n",sizeof(MY));
    MY my;
    printf("%lu\n",
【OpenFOAM】-olaFlow-算例4- irreg45degTank 不规则波浪模拟 阅读详情

相关推荐

CPD (Coherent Point Drift) 算法实现点云配准 C++

作为和icp并列的点集配准算法cpd为什么没有icp火,等我把整个方案跑完才明白。 首先下载cpd https://github.com/gadomski/cpd 包含的fgt https://github.com/gadomski/fgt 下载到win10的解压后 运行cmake来进行编译 这个时候会提醒缺少eigen3 fgt python 这几个都安装排除后 在build文件夹下会生成vs2017的源码,右键全部生成后在 .\cpd-master\build\Debug 下会生成一个cpd.li

uranus1992的博客 3499

GDB查看c/c++内存对象模型

使用GDB查看c/c++内存

a0408152的博客 950

基于Simulink的智能车辆电子稳定控制(ESC)仿真

本文完成了基于 Simulink 的智能车辆电子稳定控制(ESC),实现了:✅ 构建含轮胎非线性的车辆动力学模型✅ 设计滑模横摆稳定性控制器✅ 实现四轮制动力分配逻辑✅ 验证在双移线低附着场景下的卓越稳定性✅ 为主动安全控制系统开发提供完整范式。

xiaoheshang_123的博客 59

C++ 内存模型

C++内存模型

sssxlxwbwz的博客 2343

GDB查看C++对象布局

GDB查看C++对象布局 C++类包含数据成员(static,nonstatic)和成员函数(static、nonstatic、virtual)。 C++对象模型完成对数据成员和成员函数的构建。本文对以下模型的构建进行分析: 单一类 单继承无重写 单继承有重写 多继承 虚继承 菱形继承 单一类 class Base{ public: Base():m_base(0){} vir...

tmhanks的博客 5337

C++对象内存模型

C++对象内存模型 C语言中数据和处理数据的函数是分别定义,各个处理数据的函数实现相应各种算法。但是C++提供了类,可以实现较好的数据和处理数据的算法的封装性,这种封装性相比较C语言而言会带来一些成本,这主要受制于是C++对象为支持相应特性而实现的内存模型C++程序内部格局通常分为四个区: 全局数据区:静态数据和常量 代码区:所以类成员函数和非成员函数代码 栈区:就是那些由编译器在需...

King逍灬遥 1476

C++对象内存模型

虚函数表 #include using namespace std; class Father { public: Father(){}; void ShowName(){ cout"Father"<<endl; } }; class Son : public Father { public: Son(){}; void ShowNa

Sundrops的专栏 7165

一文读懂C++虚函数的内存模型

一文彻底读懂C++虚函数表的实现机制(使用GDB内存布局)1、虚函数简介2、虚函数表简介3、有继承关系的虚函数表剖析3.1、单继承无虚函数覆盖的情况3.2、单继承有虚函数覆盖的情况3.3、多重继承的情况3.4、多层继承的情况4、总结 1、虚函数简介 C++中有两种方式实现多态,即重载和覆盖。 重载:是指允许存在多个同名函数,而这些函数的参数表不同(参数个数不同、参数类型不同或者两者都不同)。 覆盖:是指子类重新定义父类的虚函数的做法,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际

游戏行业资深搬砖人员 1万+

一文读懂C++虚继承的内存模型

一文读懂C++虚继承的内存模型1、前言2、多继承存在的问题3、虚继承简介4、虚继承在标准库中的使用5、虚继承下派生类的内存布局解析6、总结 1、前言 C++虚继承的内存模型是一个经典的问题,其具体实现依赖于编译器,可能会出现较大差异,但原理和最终的目的是大体相同的。本文将对g++中虚继承的内存模型进行详细解析。 2、多继承存在的问题 C++的多继承是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。从概念上来讲这是非常简单的,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突

游戏行业资深搬砖人员 1万+

C++内存模型

C++内存模型: 栈的地址是由高到低的,而堆却相反 当char变量在前面的时候,char占一个字节, 但是为了提升效率和性能,需要进行补足4的倍数,因此需要再加上3个字节,因此,下一变量int和上一个变量相差8个字节, 但是如果int变量在char之前,由于int占四个字节,因此不会出现这种情况,地址紧接着存储 (gdb) p &c $1 = 0x7fffffffe4ff "" (gd...

qq_38304320的博客 313

C++内存模型以及寄存器指针rsp和rbp

内存栈顶指针sp偏移 系统Ubuntu-18.04 环境gcc 7.5.0 代码段1 #include <iostream> using namespace std; int main(){ char ch = 'a'; int num1 = 1; return 0; } 命令g++ -g test.cpp -o test编译, 通过gdb test --...

许诺的博客 1万+

C++对象内存模型

类的存储区域可划分为:公共区域(静态成员、成员函数)、成员数据 公共区域(静态成员:所有成员均摊静态成员的大小后约等于没有、成员函数) 我们可以计算的为普通数据成员的大小;

weixin_62946182的博客 762

C++对象内存模型

类是创建对象的模板,不占用内存空间,不存在于编译后的可执行文件中;而对象是实实在在的数据,需要内存来存储。对象被创建时会在栈区或者堆区分配内存。 直观的认识是,如果创建了 10 个对象,就要分别为这 10 个对象的成员变量和成员函数分配内存,如下图所示: 不同对象的成员变量的值可能不同,需要单独分配内存来存储。但是不同对象的成员函数的代码是一样的,上面的内存模型保存了 10 份相同的代码...

qq_38325803的博客 304

C++ 学习总结】- 09 - 类的认识:类的内存模型

了解对象内存模型能够帮助我们更好地使用对象

DaveoCKII的博客 1779

c++对象内存模型【内存布局】

#类中的元素 0. 成员变量 1. 成员函数 2. 静态成员变量 3. 静态成员函数 4. 虚函数 5. 纯虚函数 #影响对象大小的因素 0.成员变量 1. 虚函数表指针(_vftptr) 2. 虚基类表指针(_vbtptr) 3. 内存对齐 _vftptr、_vbtptr的初始化由对象的构造函数, 赋值运算符自动完成;对象生命周期结束后,由对象的析构...

weixin_30340353的博客 528

C++ | C++对象内存模型

C++ | C++对象内存模型 类是创建对象的模板,不占用内存空间,不存在于编译后的可执行文件中;而对象是实实在在的数据,需要内存来存储。 对象被创建时会在栈区或者堆区分配内存。 编译器会将成员变量和成员函数分开存储:分别为每个对象的成员变量分配内存,但是所有对象都共享同一段函数代码。如下图所示: 实例1: /******************************************************************* * > File Name: classStud

I_feige的博客 1357

c++内存模型对象

一、对象 1.类对象所占用的空间 (1)类的普通成员函数不占用类对象的成员空间 (2)一个类对象至少要占用1字节的内存空间 (3)类的普通成员变量占用类对象的空间(每一个类的对象拥有属于自己的成员变量) (4)类的普通成员函数虽然写在类的定义中,但普通成员函数不会占用类对象的内存空间 (5)所有类的对象公用一份成员函数 2.C++...

weixin_30357231的博客 271

C++ 知识要点:对象内存模型

C++中,通过和->访问对象成员的主要区别在于它们的访问方式和语法。用于直接对象,而->用于通过指针间接访问对象。尽管在底层实现和性能上可能存在微小的差异,但这些差异通常被现代编译器的优化所掩盖。更重要的是要考虑代码的可读性、维护性和安全性。在实际的C++实现中,不同的编译器可能会采用不同的策略来记录虚基类子对象的偏移信息。一些编译器可能会选择将偏移信息嵌入到虚函数表中,而另一些则可能会使用额外的指针。这些选择通常取决于编译器的设计目标、性能考虑以及与其他特性的兼容性。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 1227

april tag.pdf

april tag的标志和id号AprilTag是一种视觉基准系统,适用于各种任务,包括增强现实,机器人和相机校准

基于DSP的电力线载波OFDM调制解调器

  利用电力线作为信道进行通信是解决最后一公里问题的一个很好的方法。然而电力线作为通信信道,存在着高噪声、多径效应和衰落的特点。OFDM技术能够在抗多径干扰、信号衰减的同时保持较高的数据传输速率,在具体实现中还能够利用离散傅立叶变换简化调制解调模块的复杂度,因此它在电力线高速通信系统中的应用有着非常乐观的前景。文中给出一种基于正交频分复用技术(OFDM技术)的调制解调器的设计方案。

上一篇: 基于UNIX的网络编程(理论篇:设计迭代服务器)
下一篇: C++的引用和指针的区别(&和*)
写代码的柯长
博客等级 码龄11年 84粉丝 52原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值