-- C++的数据和操作是分开存储,并且每一个非内联成员函数(non-inline member function)只会诞生一份函数实例,也就是说多个同类的对象会共用一块代码。
那么问题是:这块代码是如何区分那个对象调用自己的呢?
C++通过提供特殊对象指针,this指针来解决,this指针指向被调用的成员函数所属的对象。
C++规定,this指针是隐含在对象成员函数内的一种指针,当一个对象被创建后,它的每一个成员函数都含有一个系统自动生成的隐含指针this,用以保存这个对象的地址,this指针是C++实习封装的一种机制,它将对象和该调用对象成员函数连接在一起,在外部看来,每个对象都拥有自己的函数成员。
this指针永远指向当前对象
成员函数通过this指针即可知道操作的是那个对象的数据,this指针是一种隐含指针,它隐含于每个类的非静态成员函数中,this指针无需定义,直接使用即可。(静态成员函数内部没有this指针,静态成员函数不能操作非静态成员函数)
this指针的使用:1)当形参和成员变量名相同时,可用this指针来区分。2)在类的非静态成员函数中返回对象本身,可使用return this。
#include<iostream>
using namespace std;
class PerSon
{
public:
PerSon(int age)
{
//this指针指向的是被调用的成员函数所属的对象
this->age = age; //如果同名 没有this指针 编译器将认为3个age为同一个数据
}
void showage()
{
cout << "年龄:" << this->age << endl;
}
PerSon & Addage(PerSon & p)
{
this->age += p.age;
return *this;
}
int age;
};
void test()
{
PerSon p1(18);
//cout << "p1的年龄: " << p1.age << endl;
p1.showage();
PerSon p2(10);
p1.Addage(p2).Addage(p2).Addage(p2);//链式编程
p1.showage();
}
int main()
{
test();
return 0;
}
二、空指针
如果是一个空指针:可以访问 没有this的一些成员函数,如果函数中用到了this指针,则程序down掉。
#include<iostream>
using namespace std;
class Person
{
public:
void showclaaaName()
{
cout << "class Name is Person " << endl;
}
void showage()
{
//NULL->m_Age;
if (this == NULL)
{
return;
}
cout << "age=" << this->m_Age << endl;
}
int m_Age;
};
void test()
{
/*Person p1;
p1.m_Age = 18;
p1.showage();
p1.showclaaaName*/
Person * p1 = NULL;
p1->showage();//访问空指针
p1->showclaaaName();
}
int main()
{
return 0;
}
三、常函数和常对象
this指针本质 指针常量 type * const this
指针的指向是不可以修改的,指针指向的值可以改
如果想让指针指向的值不能修改 const type * const this
需要将成员函数改成常函数,在成员函数后面加上const
有些特例的属性:即使是常函数或者常对象 也可以修改的 需要在这个属性前加关键字 mutable
常对象 const PerSon p1;
常对象只能调用常函数 不能调用普通成员函数。
#include<iostream>
using namespace std;
class PerSon
{
public:
//成员函数声明后加const 代表常函数,不可以修改成员属性
void showPerson()const
{
//PerSon * const this
//this指针的本质 是一个指针常量,指针的指向是不可以修改的,指针指向的值是可以修改的
cout << this->m_A << endl;
//this->m_A = 100;
//this=NULL;
this->m_B = 100;
}
void showPerson2()
{
cout << "aaa" << endl;
}
int m_A;
mutable int m_B;//加上关键字 即使常函数 也可以修改
};
void test01()
{
PerSon p1;
p1.m_A = 10;
p1.showPerson();
}
//常对象
void test02()
{
const PerSon p1;//常对象 不可以修改内部属性
//p1.m_A=100;
p1.m_B = 100;//m_B是特殊属性,即使常对象或常函数 也可修改
p1.showPerson();//常对象只能调用 常函数
//p1.showPerson2();//常对象不可以调用普通函数的成员函数
}
int main()
{
test01();
return 0;
}