this指针/常函数、常对象
this指针引入
类中对象的成员变量和成员函数是分开存储的,sizeof(空class) = 1,另外示例中涉及到字节对齐的问题,double本身的字节为8,int为4,由于字节对齐,int也为8,所以最终字节数为16
class Person{
int m; //非静态成员变量,属于对象 sizeof(Person) = 4
static int n; //静态成员变量,不属于对象 sizeof(Person) = 4
static void func(); //静态成员函数,不属于对象 sizeof(Person) = 4
void func01(); //非静态成员函数,不属于对象 sizeof(Person) = 4
double p; //sizeof(Person) = 16 字节对齐 #pragma pack(1)可以取消字节对齐
};
void test01(){
cout << "sizeof(Person) = " << sizeof(Person) << endl;
}
非静态成员变量才属于对象本身,静态成员变量、函数、非静态成员函数(非内联)不属于对象本身。

每一个非内联成员函数只会诞生一份函数实例,多个同类型对象会共用一块代码,由于类中每个实例后的对象都有独一无二的地址,因此不同的实例对象调用成员函数时,函数需要知道是谁在调用它,因此引入了this指针。
this指针原理
主要作用:为了区分不同的实例对象;解决命名冲突。
this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都会含有一个系统自动生成的隐含指针this。this指针指向被调用的成员函数所属的对象(谁调用成员函数,this指向谁),*this表示对象本身,非静态成员函数中才有this,静态成员函数内部没有。
class Person{
public:
static int m_B;
int m_A;
Person(int tmp){
m_A = tmp;
}
void test(){
m_A = ;
}
static void test01(){
m_B = ;
}
};
void Class_test(){
int m = ;
Person p(m);
}
编译器对上述代码进行如下处理,对非静态成员函数默认添加了this指针,类型为class *cosnt this
struct Person{
static int m_B;
int m_A;
};
void Person_Ini(Person *const this, int tmp){ //添加了this指针
this->m_A = tmp;
}
void Person_test(Person *const this){
this->m_A = ;
}
static void Person_test01(){
m_B = ;
}
void Person_Class_test(){
int m = ;
Person p;
Person_Ini(&p, m);
}
this指针使用
一般多用于:(1)当形参与成员变量名相同时,用this指针来区分;(2)在类的非静态成员函数中返回对象本身,可以用return *this,this指向对象,*this表示对象本身。
class Person{
public:
int m_A;
Person(int m_A){
this->m_A = m_A; //为了区分形参和成员变量同名
}
//PPlus返回对象可以实现链式编程,如果没引用则返回的是this指向对象的拷贝
Person& PPlus(Person p){
this->m_A += p.m_A;
return *this; //返回对象
}
};
void test01(){
int m = ;
Person p1(m);
Person p2(m);
//---------
//
p1.PPlus(p1).PPlus(p1);
//---------
//---------
//40
//p1.PPlus(p1);
//p1.PPlus(p1);
//---------
cout << p1.m_A << endl;
}
空指针访问成员函数
注意:(1)如果成员函数没有用到this,则空指针可以直接访问;(2)若成员函数用到了this,则可以加if判断,如果this为NULL,则直接return掉。
常函数、常对象
void func() const //常函数 const Person p2; //常对象
常函数修饰的是this指针,不允许修改this指针指向的值,如果执意要修改常函数,可以在成员属性前加mutable。
常对象不允许修改属性,不可以调用普通成员函数,可以调用常函数。
class Person{
public:
int m_a;
mutable int m_b;
void test() const{
//this->m_a = 100; //加了const表示常函数,不可修改this指向的值,其实也是成员属性
this->m_b = ; //加了mutable,可以修改
}
void test02() {
this->m_a = ; //
this->m_b = ; //加了mutable,可以修改
}
};
void test01(){
const Person p;
//p.m_a = 10; //常对象,不可修改属性值
p.test();
//p.test02(); //不可调用普通函数
}
this指针/常函数、常对象的更多相关文章
- C++_向函数传递对象
向函数传递对象 1. 使用对象作为函数参数 对象可以作为参数传递给函数,其方法与传递其他类型的数据相同. 在向函数传递对象时,是通过传值调用传递给函数的. 因此,函数中对对象的任何修改均不影响调用该函 ...
- C++中常函数内部的this指针也是const类型的
代码中碰到一个奇怪的现象,在同样的函数中调用this指针,结果却有一个无法通过编译 // 读取连接信息 void ThirdWizardPage::ReadConnection() { QFile f ...
- C++中指向对象的常指针和指向常对象的指针
指向对象的常指针 将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为其初始值,不能改变. Time t1(10,12,15),t2; Time * const ptr1=&am ...
- 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)
十四 构造函数和初始化表 ... 初始化表 )语法形式 class 类名{ 类名(形参表):成员变量1(初值),...{} }; )必须要使用初始化表的场景 -->如果有类 类型的成员变量,而该 ...
- python面试总结2(函数常考题和异常处理)
python函数常考题 可变类型为参数 不能类型为参数 python如何传递参数 传递值还是引用呢?都不是.唯一支持的参数传递是共享穿参 Call by Object(Call by Object R ...
- C++:向函数传递对象(对象、对象指针、对象引用)
3.5.1 使用对象作为函数参数,其方法与传递基本类型的变量相同 //例3.21 使用对象作为函数参数 #include<iostream> using namespace std; ...
- C++中的函数指针和函数对象总结
篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址.函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. ...
- c++入门之函数指针和函数对象
函数指针可以方便我们调用函数,但采用函数对象,更能体现c++面向对象的程序特性.函数对象的本质:()运算符的重载.我们通过一段代码来感受函数指针和函数对象的使用: int AddFunc(int a, ...
- c++学习之初话 函数指针和函数对象 的因缘
函数指针可以方便我们调用函数,但采用函数对象,更能体现c++面向对象的程序特性. 函数对象的本质:()运算符的重载.我们通过一段代码来感受函数指针和函数对象的使用: int AddFunc(int a ...
随机推荐
- HDU-1754-I Hate It-线段树-求区间最值和单点修改
开学新拉的题目,老题重做,思路会稍微比之前清晰,不过这也算是一点点进步了. 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现 ...
- 剑指offer——18打印从1到最大的n位数
题目: 输入数字n,按顺序打印出从1到最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数999. 题解: 注意大数溢出问题,故使用字符串更靠谱 class Solution { pu ...
- USACO 2007 November Silver Best Cow Line /// oj21653
题目大意: 输入n 接下来n行字母 在队头和队尾中选出较小的放入新的队列 Sample Input 6ACDBCB Sample Output ABCBCD 注意相同的情况 先判断内层的大小 输出 ...
- Django ORM 之 单表、多表查询
返回ORM目录 Django ORM Django ORM 之一 内容目录: 一.单表查询 二.多表查询 0.准备工作 一些说明: - 表myapp_person的名称是自动生成的,如果你要自定义表名 ...
- 2019-8-31-C#-直接创建多个类和使用反射创建类的性能
title author date CreateTime categories C# 直接创建多个类和使用反射创建类的性能 lindexi 2019-08-31 16:55:58 +0800 2018 ...
- canvas插入图片设置背景,渐变
##在canvas中插入图片(需要image对象) 1.canvas操作图片时,必须要等图片加载完才能操作 2.drawImage(image, x, y, width, height) 其中 ima ...
- Trip
Trip 给出一个长度为n序列\(\{a_i\}\),长度为m的序列\(\{b_i\}\),求它们的不同lcs序列按字典序输出,\(n,m\leq 80\),lcs不超过1000个,字符为26个小写字 ...
- leetcode-63-不同路径②
题目描述: 第一次提交: class Solution: def uniquePathsWithObstacles(self, obstacleGrid) : m = len(obstacleGrid ...
- leetcode-90-子集②
题目描述: 方法一:回溯 class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.s ...
- 0927CSP-S模拟测试赛后总结
84pts rank28 经历了一个阶段的持续低迷,终于回到自己之前的位置了啊. 尽管依旧不是太靠上,但是还是证明了我的努力. 宿舍三人的风水轮流转之谈终究只是戏言和巧合.嘟嘟和Lockey都进第一机 ...