首页 > 编程语言 >C++this指针

C++this指针

时间:2023-04-03 19:57:39浏览次数:51  
标签:int 成员 C++ 静态 对象 Foo 指针

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

在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上

首先看一下空对象占多少空间

class Foo {

};

int main() {
    Foo foo;
    cout << "size of is : " << sizeof(foo) << endl;
}

结果为 size of p = 1;

说明空对象占用内存空间为:1

为什么是1呢?

因为C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置。
每个空对象也应该有一个独一无二的内存地址,因此编译器会给每个空对象分配一个字节作为区分。

再来看看给空对象中添加一个非静态变量

class Foo {
public:
    int m_number_1;
};

int main() {
    Foo foo;
    cout << "size of is : " << sizeof(foo) << endl;
}

结果为 size of p = 4;

说明:非静态变量m_number_1属于类的对象上

再给Foo中添加一个静态变量

class Foo {
public:
    int m_number_1;
    static int number_2;
};
int person::number_2 = 10;//static变量是在类内申明,在类外初始化的,
//并且在类外初始化的时候要加上它的作用域

int main() {
    Foo foo;
    cout << "size of is : " << sizeof(foo) << endl;
}

结果为 size of p = 4;

说明:静态变量m_number_2不属于类的对象上

最后我们再往类中添加一个非静态函数和一个静态函数

class Foo {
public:
    int m_number_1;
    static int number_2;

public:
    void Func01();
    static void Func02();
};
int person::number_2 = 10;//static变量是在类内申明,在类外初始化的,
//并且在类外初始化的时候要加上它的作用域

int main() {
    Foo foo;
    cout << "size of is : " << sizeof(foo) << endl;
}

结果都仍然为:size of p = 4;

说明:成员函数(包括静态和非静态)不属于类的对象上

综上所述:

  • 成员函数(包括静态和非静态)与成员变量分开存储
  • 只有非静态的成员变量的内存是在该类内的,其余都不在

一个思考

从上面的结论可以引发一个思考,非静态成员函数是不属于类对象的,非静态成员函数是单独存储在一个空间中的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。

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

this指针

一、this指针的定义和用法

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

this指针是隐含每一个非静态成员函数内的一种指针,this指针不需要定义,直接使用即可。

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this
class Foo {
public:
    int m_num;

public:
	PFoo(int m_num){
		//1、当形参和成员变量同名时,可用this指针来区分
		this->m_num = m_num;
	}
 
	Foo& FooAddFoo(Foo f){
		this->m_num += f.m_num;
		//2、返回对象本身
		return *this;
	}
	
};
 
int main() {
	Foo f1(20);
	cout << "f1.m_num =  " << f1.m_num << endl;
 
	Foo f2(10);
	f2.FooAddFoo(f1).FooAddFoo(f1);	  // 等价于:(f2.FooAddFoo(f1)).FooAddFoo(f1);
                                      // 10 + 20 + 20
	cout << "f2.m_num = " << f2.m_num << endl;

	return 0;
}

二、this指针的本质--指针常量

this指针的本质是一个指针常量:const Type* const pointer;

他储存了调用他的对象的地址,并且不可被修改。这样成员函数才知道自己修改的成员变量是哪个对象的。

例如:调用date.SetMonth(9) <===> SetMonth(&date, 9),this指针帮助完成了这一转换,使得this指针指向了调用对象data。

三、this指针的特点

1.只能在成员函数中使用,在全局函数、静态成员函数中都不能使用 this(this始终指向当前对象,静态成员函数属于类)

  1. this 指针是在成员函数的开始前构造,并在成员函数的结束后清除(和函数的其他参数生命周期一样)

  2. this 指针会因编译器不同而有不同的存储位置,可能是栈、寄存器或全局变量 (编译器在生成程序时加入了获取对象首地址的相关代码并把获取的首地址存放在了寄存器中)

  3. 关于this指针的一个经典回答:

当你进入一个房子后,你可以看见桌子、椅子、地板等,但是房子的全貌 ,你看不到了

  
对于一个对象(也就是类的实例)来说,你可以看到它的成员函数、成员变量,但是看不到对象本身了

所以有了this指针,它时时刻刻指向你这个对象本身

标签:int,成员,C++,静态,对象,Foo,指针
From: https://www.cnblogs.com/Bdathe/p/17284156.html

相关文章

  • c++类型推导
    传统c和c++中,无论什么变量都应该先去声明其类型,指出其类型后才能进行下一步操作,这通常会花费很多无意义的时间。c++11引入了auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。这使得C++也具有了和其他现代编程语言一样,某种意义上提供了无需操心变量类......
  • c++运行时间记录
    chrono::steady_clock::time_pointt1=chrono::steady_clock::now();......chrono::steady_clock::time_pointt2=chrono::steady_clock::now();chrono::duration<double>time_used=chrono::duration_cast<chrono::duration<double>>(t2-t1);......
  • 《c++徒步》基础语法篇
    trycatch原文链接:https://www.dotcpp.com/course/84语法结构:try{ //正常程序执行语句 throw(异常类型表达式);}catch(异常类型1){ //异常处理代码}catch(异常类型2){ //异常处理代码}catch(异常类型3){ //异常处理代码}//后续代码实例:#include<iostream......
  • linux下的c++filt 命令查找未定义符号的函数名
    我们知道,在C++中,是允许函数重载的,也就引出了编译器的namemangling机制,今天我们要介绍的c++filt命令便与此有关。   对于从事linux开发的人来说,不可不知道c++filt命令的使用。    在linux开发中,如果要调用基础模块库,就要包含对应的头文件,并在makefile中指......
  • C++17:新特性之std::optional
    考虑一个问题,C++如何实现返回多个值?如何标记其中一个bool返回值用于记录函数运行状态?我们可以通过pair或tuple实现,有以下代码:#include<iostream>#include<string>usingnamespacestd;structss{ strings; intsize;};pair<bool,ss>func2(conststring&in){......
  • C++黑马程序员——P55. 函数的分文件编写
    函数分文件编写一般有4个步骤1.创建后缀名为.h的头文件2.创建后缀名为.cpp的源文件3.在头文件中写函数的声明4.在源文件中写函数的定义 1.创建后缀名为.h的头文件右键项目的“头文件”文件夹->添加->新建项->然后中间选“头文件(.h)”,下面起个名字,添加2.......
  • 快慢指针-小记
    快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。最后,慢指针就是中位数。这个理论,是建立在中位数=n/2的基础上。同时,适用于:单向链表查找。这个理论,需要一个简易的规律总结即可自证。[1,2,3]l......
  • vsc debug C++
    mac{"version":"0.2.0","configurations":[{"name":"(lldb)Launch","type":"cppdbg","request":"launch","program":......
  • C++:实现RAII机制
    RAII,也称资源获取即初始化,要求资源的有效期与持有资源的对象的生命期严格绑定,不会出现内存泄漏等问题。我们尝试将指针封装到RAII类中,实现自动析构。#include<iostream>usingnamespacestd;template<typenameT>classRAII{public: RAII():data(nullptr){} explic......
  • C++ Primer 第五版 第十一章 练习题编程题目答案
    https://github.com/jzplp/Cpp-Primer-Answer练习11.1map用关键字索引,是一个字典。vector用整数索引,是一个列表。练习11.2list链表vector顺序列表deque双端队列map字典set集合练习11.311.3map单词计数程序代码练习11.411.4去标点map单词计数程序代码练习11.5如果关键......