this指针介绍:
c++中成员变量和成员函数分开存储,每一个非静态成员函数只会有一个实例,多个同类型对象共用这一个成员函数。那么代码怎么区分哪个对象调用自己呢?this指针由此应运而生。
c++通过提供对象指针,this指针。this指针指向被调用的成员函数所属的对象,当创建一个对象时,编译器会初始化一个this指针,指向创建的的对象,this指针并不存储在对象内部,而是作为所有非静态成员函数的参数。this指针不需要定义,直接使用即可。
当写下如此代码时
void Person::setName(string name) {_name = name;
}
string Person::getName() {return _name;
}
当创建对象per时,编译器会初始化一个this指针指向对象per,通过per调用成员函数setName()和getName()时,编译器会将this指针作为两个函数的参数,编译后的代码可以表现为如下形式。下面代码演示的过程是隐含的,由编译器完成。
void Person::setName(Person* this, string name) {this->_name = name;
}
string Person::getName(Person* this) {return this->_name;
}
this指针的用途
(1)防止成员变量和成员函数的形参重名带来的异常
void Person::setName(string name) {this->name = name;
}
如果不用this指针,编译器在赋值时无法区分成员变量和形参,如下会产生异常
void Person::setName(string name) {name = name;
}
(2)如果类的成员函数返回值为一个对象,则可以用return *this返回对象本身(需要引用的方式传回);
#include <iostream>
using namespace std;
#include<string>
class Person {
public:string name;
public:void setName(string name);string getName();Person& test(Person &person1);
};
void Person::setName(string name) {this->name = name;
}
string Person::getName() {return this->name;
}
Person& Person::test(Person &person1) {this->name += person1.name;cout << "this:" << this << endl;return *this;
}
int main() {Person person1;person1.setName("张三");Person person2;person2.setName("李四");cout << "调用person2.test(person1)传回的对象的地址:" << &(person2.test(person1)) << endl;cout << "person2的对象地址:" << &person2 << endl;cout << person2.getName();return 0;
}
如果不用引用的方式传回,传回的就不是person2了,传回的是复制品
关于this指针的一些问题
当this指针为空时,有一个问题需注意
#include <iostream>
using namespace std;
#include <string>
class Person {
public:string name;
public:void f();void setName(string name);
};
void Person::f() {cout << "调用f(),没用到this指针是可以正常调用的" << endl;
}
void Person::setName(string name) {this->name = name;//无法正常调用,因为this指针为空,读取访问异常
}
int main() {Person *person = NULL;person->f();//可以正常调用person->setName("张三");//无法正常调用
}
当我们声明了Person *person = NULL后,person对象在调用函数时,this指针会指向person,this这时为空,在使用this的时候就有异常,改进如下
void Person::setName(string name) {if(this!=NULL){this->name = name;}
}
跳过此行代码不执行。。。