C++对象模型和this指针

2023-11-07

C++对象模型和this指针

成员变量和成员函数分开存储

在C++中,类内的成员变量成员函数分开存储

只有非静态成员变量才属于类的对象

#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		mA = 0;
	}
	//非静态成员变量占对象空间
	int mA;
	//静态成员变量不占对象空间
	static int mB; 
	//函数也不占对象空间,所有函数共享一个函数实例
	void func() {
		cout << "mA:" << this->mA << endl;
	}
	//静态成员函数也不占对象空间
	static void sfunc() {
	}
};

int main() {

	cout << sizeof(Person) << endl;

	system("pause");

	return 0;
}



this指针概念

在C++中成员变量成员函数分开存储的

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

那么问题是:这一块代码是如何区分那个对象调用自己的呢?

c++通过提供特殊的对象指针(this指针),解决上述问题。this指针指向被调用的成员函数所属的对象

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

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

this指针的本质是一个指针常量,指针的指向不可修改


this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分

  • 在类的非静态成员函数中返回对象本身,可使用return *this

#include <iostream>
using namespace std;
class Person
{
public:
	Person(int age)
	{
		//1、当形参和成员变量同名时,可用this指针来区分
		this->age = age;
	}

	Person& PersonAddPerson(Person p)
	{
		this->age += p.age;
		//返回对象本身
		return *this;
	}

	int age;
};

void test01()
{
	Person p1(10);
	cout << "p1.age = " << p1.age << endl;

	Person p2(10);
	p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
	cout << "p2.age = " << p2.age << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}



空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

如果用到this指针,需要加以判断保证代码的健壮性

#include <iostream>
using namespace std;
//空指针访问成员函数
class Person {
public:

	void ShowClassName() {
		cout << "我是Person类!" << endl;
	}

	void ShowPerson() {
		if (this == NULL) {
			return;
		}
		cout << mAge << endl;
	}

public:
	int mAge;
};

void test01()
{
	Person * p = NULL;
	p->ShowClassName(); //空指针,可以调用成员函数
	p->ShowPerson();  //但是如果成员函数中用到了this指针,就不可以了
}

int main() {

	test01();

	system("pause");

	return 0;
}



const修饰成员函数

常函数:

  • 成员函数后加const后我们称为这个函数为常函数

  • 常函数内不可以修改成员属性

  • 成员属性声明时加关键字mutable后,在常函数中依然可以修改

常对象:

  • 声明对象前加const称该对象为常对象

  • 常对象只能调用常函数

this指针的本质是一个指针常量指针的指向不可修改

如果想让指针指向的值也不可以修改,需要声明常函数

#include <iostream>
using namespace std;
class Person {
public:
	Person() {
		m_A = 0;
		m_B = 0;
	}

	//this指针的本质是一个指针常量,指针的指向不可修改
	//如果想让指针指向的值也不可以修改,需要声明常函数
	void ShowPerson() const {
		//const Type* const pointer;
		//this = NULL; //不能修改指针的指向 Person* const this;
		//this->mA = 100; //但是this指针指向的对象的数据是可以修改的

		//const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量
		this->m_B = 100;
	}

	void MyFunc() const {
		//mA = 10000;
	}

public:
	int m_A;
	mutable int m_B; //可修改 可变的
};


//const修饰对象  常对象
void test01() {

	const Person person; //常量对象  
	cout << person.m_A << endl;
	//person.mA = 100; //常对象不能修改成员变量的值,但是可以访问
	person.m_B = 100; //但是常对象可以修改mutable修饰成员变量

	//常对象访问成员函数
	person.MyFunc(); //常对象只能调用const的函数

}

int main() {

	test01();

	system("pause");
	return 0;
}

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

C++对象模型和this指针 的相关文章

  • 用 C++ 进行服装建模 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在编写一些软件 最终会绘制一个人体框架 可以配置各种参数 并且计划是在假人身上放置某种衣服 我研究
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 使用 Unity 在构造函数中使用属性依赖注入

    好的 我在基类中定义了一个依赖属性 我尝试在其派生类的构造函数内部使用它 但这不起作用 该属性显示为 null Unity 在使用 container Resolve 解析实例后解析依赖属性 我的另一种选择是将 IUnityContaine
  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • Web2.0网站一些通用业务采用NoSql的解决方案

    首先理解NoSql的划分 Often NoSQL databases are categorized according to the way they store the data and fall under categories su
  • MySQL生产环境高可用架构实战

    分布式技术MongoDB 1 MySQL高可用集群介绍 1 1 数据库主从架构与分库分表 1 2 MySQL主从同步原理 2 动手搭建MySQL主从集群 2 1 基础环境搭建 2 2 安装MySQL服务 2 2 1 初始化MySQL 2 2
  • 仿射密码 affine

    参考链接 https www cnblogs com 0yst3r 2046 p 12172757 html 仿射加密法 在仿射加密法中 字母表的字母被赋予一个数字 例如 a 0 b 1 c 2 z 25 仿射加密法的密钥为0 25直接的数
  • Incorrect integer value: '' for column 'id' at row 1 错误解决办法

    最近一个项目 在本地php环境里一切正常 ftp上传到虚拟空间后 当执行更新操作 我的目的是为了设置id为空 set id 时提示 Incorrect integer value for column id at row 1 解决办法 方法
  • 广工人福利,openwrt+gduth3c通过inode认证,妈妈再也不用担心我要用电脑开wifi了

    刚开校园网的时候 天天都只能用电脑开wifi 用类似于360wifi 猎豹wifi之类的软件要经常开着电脑 而且电脑网卡发射功率又小 上个厕所wifi就断了 睡觉前在床上还没wifi用 超级不爽 于是从家里面拿来了放在自己房间挂迅雷百度云的
  • x86下的C函数调用惯例

    1 从汇编到C 1 1 汇编语言的局限性 汇编语言是一种符号化了的机器语言 machine code 即用指令助记符 符号地址 标号等符号书写程序的语言 汇编语句与机器语句一一对应 它只是把每条指令及数据用便于记忆的符号书写而已 汇编语言
  • 用自己的数据增量训练预训练语言模型

    预训练模型给各类NLP任务的性能带来了巨大的提升 预训练模型通常是在通用领域的大规模文本上进行训练的 而很多场景下 使用预训练语言模型的下游任务是某些特定场景 如金融 法律等 这是如果可以用这些垂直领域的语料继续训练原始的预训练模型 对于下
  • spring配置文件解读——applicationContext.xml

    spring的配置文件 applicationContext xml 听着晴天看星晴的博客 CSDN博客
  • binutils internal struct

    http fossies org dox binutils 2 23 2 structelf internal sym html dl iterate phdr REPAIR RAX inline hook
  • [动态规划] leetcode 416. 分割等和子集

    问题描述 分割等和子集 给你一个只包含正整数的非空数组 nums 请你判断是否可以将这个数组分割成两个子集 使得两个子集的元素和相等 例子 输入nums 1 5 11 5 输出true 动态规划求解 这是一个0 1背包问题的变种 也就是每种
  • Idea工具使用经典总结

    安装教程 下载地址 https www jetbrains com idea download section windows 准备idea ideaIU 2017 2 3 exe 软件与激活包 JetbrainsCrack 2 6 9 r
  • 设备节点如何与设备驱动关联

    1 上层应用如何调用设备驱动 1 在linux中一切皆是文件 设备驱动程序对上层应用程序来说和普通文件没什么差异 2 上层应用程序通过设备节点来访问驱动程序 在驱动程序注册到内核后 用申请到的主次设备号来创建设备节点 2 向内核注册字符驱动
  • 【已解决】Error: Unable to access jarfile .\xxxx.jar

    报错类型 Error Unable to access jarfile xxxx jar 复现工具的时候 通过命令 java jar xxxx jar 运行 jar 包报了这个错误 报错原因是 在命令行中出现的路径下找不到 xxxx jar
  • micro-app在vue-element-admin中一些使用研究

    1 简述 本文承接上一篇micro app在vue element admi中的搭建 对micro app在vue element admin中的一些平时开发中常用的功能做了一些研究 本文代码 2 路由 关于路由 这边从两方面进行研究 一方
  • ass字幕格式

    ssa ass字幕格式全解析 内容 一 概述 二 文件各个部分解析 三 各种类型的行 四 Script Info 部分的标题行 五 v4 Styles 部分的风格行Style 六 Events 事件部分的对话行Dialogue 七 Even
  • 高通功耗调试18之Tsensor中断频繁触发导致低温下待机功耗高的问题

    问题背景 在内核4 9及之后的版本 低于5C环境温度下待机 由于触发了Tsensor的低温保护机制 可能会遇到较频繁 的tsens中断 11 22 07 12 27 914969 0 0 W GICv3 gic show resume ir
  • [echarts]柱状图的点击事件

    先来一段简洁的写echarts图表的代码 这样获取echarts的dom节点是因为 如果将柱状图封装成了一个组件 在一个页面中多次使用 若还是按常规获取dom节点 会报一个警告 let charts echarts getInstanceB
  • Linux驱动开发(应用程序如何调用驱动)

    1 添加读写接口 1 在应用代码中 2 在驱动代码中 2 应用和驱动之间的数据交换 1 copy from user 用来将数据从用户空间复制到内核空间 2 copy to user 用来将数据从内核空间复制到用户空间 3 write和re
  • DAPM之一:概述

    DAPM Dynamic Audio Power Management 对应结构体是snd soc dapm widget和snd soc dapm route 对应的操作函数是snd soc dapm new controls snd s
  • C++对象模型和this指针

    C 对象模型和this指针 成员变量和成员函数分开存储 在C 中 类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 include