this指针
this指针的用途
静态成员函数中是没有办法访问非静态变量的,普通函数中是可以访问非静态变量的。
在main函数中创建对象p1,其实类中的成员函数的括号中隐藏着一个this指针,如果p1调用的这个函数,那么这个this就指向的是p1这个对象。通过this指针指向谁能够让函数区分出来是谁在调用这个函数。
this指针 指向的是 被调用的成员函数 所属的对象。比如说p1对象调用有参构造,那么有参构造中的this指针指向的就是p1,所以this->age也就是相当于p1.age。
但是你写构造函数的时候不能直接写:
class Person
{
Person(int age)
{
p1.age = age;
}
int age;
}
//这样写构造函数让其他的对象还怎么调用,
//但是又不能直接:
Person(int age)
{
age = age;
}
//这样写编译器会混淆
//所以应该是:
Person(int age)
{
this->age = age;
}
//this指向的就是调用这个构造函数的对象。
this的第一个用途就是解决名称冲突(见上),this的类型就是对象的指针的类型。
当然如果写的时候是规范的,或者传的是另一个对象,那么使用相同的成员变量的时候也就不会起冲突,不需要加this。
第二个用途
class Person
{
public :
int age;
public :
Person& PersonAddAge(Person& p)
{
this->age = this->age + p.age;
return *this; //*this就是本体
}
};
void test()
{
Person p1;
p1.age = 10;
Person p2;
p2.age = 10;
p1.PersonAddAge(p2).PersonAddAge(p2).PersonAddAge(p2);//这种写法叫做链式编程。
cout << p1.age << endl;
}
int main()
{
test();
return 0;
}
这段代码的最终结果是40。Person& 作为返回值类型,返回的就是成员对象。
如果对这个PersonAddAge函数做一下修改:
Person PersonAddAge(Person& p)
{
this->age = this->age + p.age;
return *this; //*this就是本体
}
按照上面的代码运行完以后,得到的结果是20。因为返回值不再是成员对象本体,而是成员的值,只要是返回的是值,那么就会调用拷贝构造函数,所以会拷贝出一个新的东西pp,这个pp和p1是一样的,但是毕竟不是同一个东西,所以下一次的年龄相加函数的结果会产生在新对象pp上,而不是p1上。pp变成30,返回的是pp的值,所以依旧会调用pp的拷贝构造函数,产生新的对象ppp,然后继续调用函数,ppp的值最后会变成40,但是和p1是没有关系的。
总结:如果返回的是引用,那么永远都是在对p1进行操作。如果返回的不是引用,而是值,那么就会调用拷贝构造函数,进而产生新的对象,在新的对象上进行操作,产生的变化不再能够影响到p1对象。
如果需求改变了,不是让p1的年龄持续相加,而是将p1的年龄加上p2的年龄后变成p3的年龄,创建p3对象。那么就不需要返回Person&,直接将构造函数产生的新副本数据(新对象)给p3就行了。
空指针访问成员函数
class Person
{
public:
int m_age;
void showAge()
{
cout << m_age << endl;//相当于 this->m_age;
}
void showClass()
{
cout << "Person" << endl;
}
};
int main()
{
Person* p = NULL;
p->showAge();
p->showClass();
return 0;
}
结果是showClass可以调用,showAge是不能调用的,因为调用成员函数会将函数中的this指针指向调用函数的对象,在showAge中的小括号中,this指针已经指向了NULL,而NULL是不能调用m_age的。而showClass只是打印了一句话,与对象没有关系。
防止措施:
void showAge()
{
if (this == NULL)
{
return;
}
cout << m_age << endl;
}
加一个if,如果是空就直接return掉。