c++基础复习——c++对象模型和this指针

2023-11-14

1.在c++中,成员变量和成员函数分开存储

只有非静态的成员变量才属于类的变量上,成员变量和成员函数是分开存储的

  • 当定义一个空类,求空类的大小
#include <iostream>
using namespace std;

class Person
{
    
};


void test1()
{
    Person p;
    cout << "size of person = " << sizeof(p) << endl;
}

int main()
{
    test1();
    return 0;
}

原因:c++为每个空对象都分配一个字节的空间,是为了区分每个空对象的在内存中的位置;

  • 当类中存放多个非静态成员变量
class Person
{
    int a;
    int b;
};

返回值:8

原因:每个成员变量占4个内存空间

  • 存放静态成员变量或者静态成员函数

返回:1个字节

原因:静态成员变量或者静态成员函数,不属于类的对象上

  • 非静态成员函数

返回:1个字节空间

原因:非静态成员函数也不属于类的对象上

2.this指针

c++中的成员变量和成员函数是分开存储的

每一个非静态成员函数只会诞生一个函数实例,也就是说多个同类型的对象会共有同一块代码

那么问题在于:这一块代码是怎么区分哪个对象调用的自己

 

c++中通过this指针解决上述问题,this指针指向被调用的成员函数所属的对象

(比如对象p1,p2,p3,当调用p1时候,this指针就指向p1)

this指针是隐含每一个非静态成员函数内的一种指针

this指针不需要定义,直接使用

this指针的用途:

  • 当形参与成员变量同名的时候,可以用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可以用return *this
#include <iostream>
using namespace std;

class Person
{
public:
    Person(int age)
    {
        //第一个用法,形参与成员变量同名的时候,可以用this指针来区分
        //this指针指向被调用成员函数所属的对象
        this->age = age;
    }

//这里返回的是引用,不会调用拷贝构造函数
    Person& personaddage(Person &p)
    {
        this->age +=p.age;
        //this指向p2的指针,而*this指向的就是p2
        return *this;
    }
    int age;
};

void test01()
{
    Person p1(16);
    cout << "p1的age" << p1.age << endl;
}

void test02()
{
    Person p1(10);
    Person p2(10);
    p2.personaddage(p1).personaddage(p1).personaddage(p1);
}

TIPS: 

  • 如果返回的是值,那么就会调用拷贝构造函数,并不是返回本身,而是返回一个副本(p2',p2'')

  • 如果返回的是引用,那么就是返回的本身,并且不会调用拷贝构造函数

3.空指针调用成员函数

#include <iostream>
using namespace std;

class Person
{
public:
    Person()
    {
        cout << "this is class" << endl;
    }

    void show()
    {
        //报错的原因是传入的指针为空
        //所以为了保证代码的健壮性,会加入:
        if(this == NULL)
        {
            return;
        }
        cout << "name is " << this->age << endl;
    }
    int age;
};

void test01()
{
    Person *p1 = NULL;
}

4.const修饰成员函数

常函数

  • 成员函数后加const后我们称之为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加上关键字mutable后,在常函数中依然可以修改

常对象

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数
#include <iostream>
using namespace std;

class Person
{
public:
//this 指针的本质是指针常量,指针的指向是不可以修改的
//如果调用对象p,this指针就不能修改指向
//但是this指针指向的值可以修改
// const person* const this
//在成员函数后面加const修饰的是this指针,让指针指向的值也不可以修改
    void showperson() const 
    {
        this->m_a = 100;
    }
    int m_a
    mutable int m_b; //加上mutable之后,即使在常函数中,也可以修改这个值
};

void test01()
{
    Person *p1 = NULL;
    const Person p;//常对象中也不可以修改普通的成员对象
                //常对象只能调用常函数
                //因为常对象不可以修改属性,普通函数可以修改属性,所以常对象不可以调用普通成员函数
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++基础复习——c++对象模型和this指针 的相关文章

  • C++全局变量

    规则 全局变量只能在头文件申明 不能在头文件定义 工程全局变量 声明方式是头文件中extern 来声明 原因是如果放在global h中定义的话 就会出现global obj和other obj定义冲突的问题 global h extern
  • C++ 类中protected的通俗解释

    举个例子 假如我们要定义人这个类 其中每个人都有三种财富 养老金 子女金 生活金 首先是生活金 每个人的生活金其实都是可以对外公开的 所以应该可以设置为public 但是遗产和养老金是不对外公布的 那么问题来了 遗产和养老金是不是都应该设置
  • 编程小记—— C/C++中 x & -x 表示含义

    说明 看多了各种优秀看源代码的经常会遇到一些很常见的公式 本篇文章记录的 x x 就是其中的一种 含义 我们都知道 x 的值 其实就是在x的值的基础上进行按位取反 x 之后在增加1所得 也就是说 x x x x 1 x 为偶数 我们都知道
  • 引用 C C++

    引用 引用是一个别名 它的作用就是作为目标的别名而使用 对这个引用的改动 就是对目标的改动 定义 例如引用一个整型变量 int a 666 int ra a 引用运算符 与地址操作符使用相同的符号 虽然它们显然是彼此相关的 但它们又是不一样
  • dlopen和 dlsym的使用方式

    背景 为了把不同的逻辑解耦 一般会把各个业务封装成动态库 然后主逻辑去调用各个动态库 这里有个问题是 为什么以前我们都是通过include第三方的头文件 然后通过连接器链接动态库实现 现在却要利用dlopen呢 考虑以下情况 比如我们要用c
  • 预处理命令 条件编译

    目录 预处理命令 条件编译 1 if endif 2 ifdef endif 3 ifndef endif 预处理命令 源程序中以 开头的行称为预处理指令 预处理指令并不是C语言的语法成分 而是传给编译程序的指令 包括 宏定义 define
  • C++ OpenSSL 3.0.8 AES加解密

    2023年后 openssl进入3 0版本 openssl的加解密代码也出现了一些变化 例如编译时会有如下错误 error C4996 AES set encrypt key Since OpenSSL 3 0 如果使用OpenSSL 1
  • C++的关键字

    关键字也称保留字 是预先定义好的标识符 有其特殊的含义 auto break case char const continue default do double else enum extern float for goto if int
  • 复杂数据类型 枚举类型

    枚举 如果一个变量只有几种可能的值 可以把它定义成枚举类型 所谓 枚举 顾名思义 就是把这种类型数据可取的值一一列举出来 一个枚举型变量取值仅限于列出值的范围 例如 定义一个枚举类型weekday enum weekday Mon Tue
  • 简单的线性单向链表

    数组的不足 我们之前用的数组也是一种数据结构 数组是顺序存储的 数组逻辑关系上相邻的两个元素在物理位置上也相邻 这就导致了在对数组进行插入或删除操作时 需移动大量数组元素 并且数组的长度是固定的 而且必须预先定义 数组的长度难以缩放 对长度
  • 预处理命令 文件包括

    预处理命令 源程序中以 开头的行称为预处理指令 预处理指令并不是C语言的语法成分 而是传给编译程序的指令 包括 宏定义 define undef 文件包含 include 条件编译 if ifdef else elif endif 其他 l
  • 带参数的main函数

    为了说明带参数的main函数 我们首先来学习一下有关命令行的概念 命令行 在操作系统状态下 为执行某个程序而键入的一行字符称为命令行 命令行的一般形式为 命令名 参数1 参数2 参数3 参数n 参数之间以一个或多个空格隔开 例如 C gt
  • 类的设计与实现 设计一个游戏的某个简单过程

    大作业1 类的设计与实现 一 实验目的 掌握类的设计与实现 了解如何根据描述发现类及其成员 具备初步的面向对象分析与设计能力 二 实验内容 请选择一个你所熟悉的游戏 分析其中的某个场景所涉及的类 及其各个类的属性和行为 完成类的定义 请选择
  • C++ 堆内存分配 new delete 简谈

    堆内存 堆区 heap 是内存空间 是区别于栈区 全局数据区和代码区的内存区域 是程序在运行时申请的内存空间 new和delete new和delete是C 专有的操作符 不需要声明头文件 new是用来申请分配堆内存的 delete是用来释
  • 用指针交换两个数

    题目描述 利用指针交换用户输入的两个数 输入 测试次数t 共t行 每行两个整数 输出 共t行 每行输出交换后的两个整数 输入样例1 2 1 2 35 21 输出样例1 2 1 21 35 思路分析 用a和b两个变量把数存储下来 再用两个指针
  • C++ Windows API IsDebuggerPresent的作用

    IsDebuggerPresent 是 Windows API 中的一个函数 它用于检测当前运行的程序是否正在被调试 当程序被如 Visual Studio 这样的调试器附加时 此函数会返回 TRUE 否则 它会返回 FALSE 这个函数经
  • C++的类与对象

    类的概念 类是将不同类型的数据和处理这些数据的操作封装在一起的一个复合数据类型 类有两类成员 一类是数据成员 用于表示实体抽象的属性 另一类是成员函数 用来描述实体抽象的行为 类作为一种数据类型 在定义的时候是不分配内存的 类通过将数据和对
  • 【C/C++学习笔记】c++ 回调函数

    1 介绍 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针 地址 作为参数传递给另一个函数 当这个指针被用来调用其所指向的函数时 我们就说这是回调函数 回调函数不是由该函数的实现方直接调用 而是在特定的事件或条件发生时由另外的一方
  • 键盘输入流的缓冲效应 I/O流 缓冲I/O

    引子 有时候 你会发现 你的程序老是读不进某个值 但是反反复复看代码 又感觉自己代码真的没有问题 比如说下面这个代码 include stdio h int main int num char ch scanf d num scanf c
  • .inl文件

    背景 最近工作涉及到thrust库 看了半天也没找到一个头文件的函数定义 本来以为会有一个cpp源文件对应h头文件 后来问头文件的末尾发现了一个include lt inl gt 所以有必要了解这个文件组织形式 引用 作者 Return H

随机推荐

  • Ubuntu 安装、卸载JDK

    JDK 介绍 Open JDK 和 Oracle JDK区别 OpenJDK是Java开发工具包的开源实现 Oracle JDK是Java开发工具包的官方Oracle版本 尽管OpenJDK已经足够满足大多数的案例 但是许多程序比如Andr
  • 【Java预科】CH01 MarkDown语法

    1 标题 空格 标题名字 空格 二级标题 越多字体越小 最多只到六级 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 七级标题不存在 2 文字 加粗 在目标文字前后加 斜体 在目标文字前后加 斜体 加粗 在目标文字前后加 删除线
  • IOException parsing XML document from ServletContext resource [/<NONE>]; closed - call ‘refresh‘

    问题描述 SpringMVC项目添加ContextLoaderListener后无法启动
  • Qt事件(Event)

    事件Event 1 事件的概述 2 通过QLabel了解事件的操作 3 重写事件 4 重写鼠标按下事件 5 获取鼠标按下或移动的坐标 6 查看的QMouseEvent的信息 7 判断button的返回值 8 判断鼠标的哪个按键按下 9 判断
  • java中的throwable异常和错误

    Java中有个java lang Throwable类 这个类是Java中所有异常和错误的基类 Throwable下有两个大类那就是异常 Exception 和错误 Error Throwable 有两个重要的子类 Exception 异常
  • mysql的docker镜像数据库初始化踩坑记

    一 制作docker镜像 在当前目录新建子目录script 将数据库初始化脚本拷贝进去 后缀名为 sql 脚本执行顺序是按字母大小排序 建议可以按 1 xxx sql 2 xxx sql这样命令 Dockerfile如下 FROM mysq
  • aps和php撒意思?,aps-c画幅是什么意思

    aps c画幅是指数码相机的CCD CMOS 的尺寸与APS的C型画幅大小相仿 在25mmX17mm左右 差不多是全画幅CCD CMOS 面积的一半 也称半幅机 本文演示环境 Windows7系统 Dell G3电脑 APS C画幅意思 A
  • Android前端音视频数据接入GB28181平台意义

    技术背景 在我们研发Android平台GB28181前端音视频接入模块之前 业内听到最多的是 如何用Android或者Windows端 在没有国标IPC设备的前提下 模拟GB28181的信令和媒体流交互流程 实现GB28181整体方案的测试
  • 头文件string与string.h的区别

    头文件string与string h的区别 在C 中 include
  • wayland与linux_Linux最让人叹息的地方

    这两天有空 试了试Sway 作为一直以来的i3用户 自己的使用环境各项配置基本也是该配的都配齐了 本来不以为然 没想到真正去到Sway却发现Wayland确实流畅很多 折腾了1天 满心想着终于来到了一个Tear free的Linux环境 结
  • 表完整性约束

    介绍 认识 约束条件和数据类型宽度一样 都是可选类型 作用 用于保证数据的完整性 一致性 有哪几种约束 primary key PK 标识该字段为该表的主键 可以唯一标识的记录 foreign key FK 标识该字段为该表的外键 not
  • JDBC的URL详解

    文章目录 JDBC的URL详解 1 jdbc的格式 2 例如 3 参数详解 JDBC的URL详解 1 jdbc的格式 jdbc mysql host failoverhost port database propertyName1 prop
  • 计算机网络的认识知乎,【知乎】计算机网络这门课为何如此之难

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 操作系统和计算机网络的共同点 在于它们都是相当复杂的体系结构 如果觉得难 也许是因为自己没能产生足够的求知欲 你也说了 无聊 晦涩 而无聊感其实是没治的 对课程的热情和对女生的爱慕感其实差不多
  • Texstudio的学习(一)

    一 入门知识 1 三要素 documentclass option class usepackage option package begin 环境名称 内容 end 环境名称 2 命令符号 1 documentclass option c
  • 东北大学c++实验(第二周)

    include
  • vim教程

    文章目录 1 移动光标 2 进入和退出 3 删除 4 插入 5 撤销 7 定位及文件状态 8 搜索类 9 匹配括号的查找 10 将文本里的某个字符串全部替换 11 在 VIM 内执行外部命令的方法 12 关于保存文件的更多信息 13 一个具
  • 【NLTK】安装和使用NLTK分词和去停词

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 黄聪 Python NLTK自然语言处理学习 一 环境搭建 http www cnblogs com huangcong archive 2011 08 29 215743
  • Matlab 三角函数(sin)

    a 这是一个三角函数 t 0 0 01 2 pi 从0到2pi 步长是0 01 y sin t plot t y 画坐标
  • java Map集合用stream流的方式遍历

    Map
  • c++基础复习——c++对象模型和this指针

    1 在c 中 成员变量和成员函数分开存储 只有非静态的成员变量才属于类的变量上 成员变量和成员函数是分开存储的 当定义一个空类 求空类的大小 include