引入
C++有一个用的极其广泛但很多地方没有明确说明的指针——this指针。简单的说,this指针是一个特殊的指针。当类的某个非静态的成员函数在执行时,this指针指向类的一个对象,且这个对象的某个成员正在被调用,并作为隐含参数传递给每一个被声明的成员函数。(换句话说,对于定义过的一个具体的class MyClass
类型的object,this指向它的条件是它的某一个成员正在被调用。)
补充:类与对象,成员
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
简单来说类就是现实中一些具有共同特性事物的抽象,它包括这个事物的一些属性和你想对这个事物的操作,而对象就是对一个类的实例化。比如你现在想要买10台电脑,这10台电脑的总和就是一个类他们就有共同的特征,现在你想给其中一台装一个软件,这一个就是这个类实例化出来的对象,你对这个对象的操作并不影响其他9 个产生影响。
类中的元素称为类的成员:类中的数据称为类的属性或者成员变量; 类中的函数称为类的方法或者成员函数。
This指针
在实际的程序中,this指针用的最多的地方是作为返回值。使用this指针可以允许成员函数返回调用对象给调用者。这一点在运算符重载中尤为重要
this指针的特性
-
this指针的类型:类类型* const
-
只能在“成员函数”的内部使用
-
this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
-
this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
事实上,编译器在编译类的时候,先识别类名,再识别类中的成员变量,然后识别类中的成员函数,对类中的成员函数改写(就是要加this指针)
下面附上一段this指针的使用范例:
// this指针的使用
#include <iostream>
#include <string.h>
using namespace std;
class Date
{
private:
int mo, da, yr;
char *month; // 改成int*就可以后面用enum类型了
public:
Date(int m = 0, int d = 0, int y = 0);
~Date();
Date &operator=(const Date &); // 声明“=”运算符重载
void display() const; // const的函数不能对其数据成员进行修改操作
};
Date::Date(int m, int d, int y)
{
static char const *mon[] = // 要注意这里char*是为了存字符串,所以必须加const
{ // 否则C++17会报错
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
mo = m;
da = d;
yr = y;
if (m)
{
month = new char[strlen(mon[m - 1]) + 1];
strcpy(month, mon[m - 1]);
}
else
{
month = 0; // NULL
}
}
Date::~Date()
{
delete[] month; // 避免内存泄漏
}
Date& Date::operator=(const Date &dt)
{
if (this != &dt)
{
mo = dt.mo;
da = dt.da;
yr = dt.yr;
delete[] month; // new体系中没有对应于realloc函数的
if (dt.month)
{
month = new char[strlen(dt.month) + 1];
strcpy(month, dt.month);
}
else
month = 0;
}
return *this; // 一定是要返回this指针指向的值
}
void Date::display() const
{
if (month)
{
cout << month << ends << da << ends << yr << endl;
}
}
int main(int argc, char const *argv[])
{
Date birthday(9, 27, 2001);
Date oldDay, newDay;
oldDay = newDay = birthday;
birthday.display();
oldDay.display();
newDay.display();
return 0;
}
实验结果: