1.this指针
在C++中,每一个对象都能通过this指针来访问自己的地址。this指针是所有成员函数的隐含参数。因此,在成员函数中它可以用来指向调用该成员函数的对象。友元函数没有this指针,因为友元不是类的成员,只有成员函数才有this指针。使用this指针实例如下所示:
1#include <iostream> 2 3using namespace std; 4 5class Box 6{ 7public: 8 // 构造函数定义 9 Box(double l = 2.0, double w = 3.0, double h = 4.0) : length(l), width(w), height(h) 10 { 11 cout << "这是Box的构造函数...\n"; 12 } 13 // 普通成员函数 14 double Volume() 15 { 16 return length * width * height; 17 } 18 19 int compare(Box box) 20 { 21 return this->Volume() > box.Volume(); 22 } 23 24private: 25 int length; 26 int width; 27 int height; 28}; 29 30int main() 31{ 32 Box box1(3.3, 2.1, 1.5); 33 Box box2(8.5, 6.0, 2.0); 34 if (box1.compare(box2)) 35 cout << "box2 小于 box1\n"; 36 else 37 cout << "box2 大于等于 box1\n"; 38 return 0; 39}
当我们调用成员函数时,实际上是替某个对象调用它。成员函数通过一个名为this的额外隐式参数来访问调用成员函数的那个对象。当我们调用一个成员函数时,用请求该函数的对象地址来初始化this。例如,如果调用total.isbn(),则编译器负责把total的地址传递给isbn的隐式形参this,因此可以等价地认为编译器将该调用重写成了以下形式:
1//伪代码,用于说明调用成员函数的实际执行过程。其中,调用Sales_data类的isbn成员函数时传入了total对象的地址 2Sales_data::isbn(&total)
因为this总是指向当前对象的指针,所以this是一个常量指针,我们不允许改变this中保存的地址。
1#include <iostream> 2 3using namespace std; 4 5class Rect 6{ 7public: 8 Rect() {} 9 ~Rect() {} 10 Rect *get_address() 11 { 12 return this; // 指针函数,返回this的地址 13 } 14}; 15 16int main() 17{ 18 Rect r1, r2; 19 // Rect* 定义指针p接受对象r1的get_address()成员函数的返回值,并打印 20 Rect *p = r1.get_address(); 21 cout << "通过this指针来返回调用get_address()成员函数的对象r1的地址p = " << p << endl; 22 p = r2.get_address(); 23 cout << "通过this指针来返回调用get_address()成员函数的对象r2的地址p = " << p << endl; 24 return 0; 25}
2.赋值运算符返回*this的应用
关于赋值运算符,你可以写成下面的连续赋值形式:
1int x, y, z; 2x = y = z = 666;
由于赋值运算符采用右结合律,因此上面的连续赋值形式可以被解析成:
1int x, y, z; 2x = (y = (z = 666));
对于自定义的类,为了能够实现连续赋值。赋值运算符应遵循如下两点规则:a.返回类型是一个当前类的引用b.返回*this给左边的变量
1class Widge{ 2public: 3 // ... 4 Widge& operator= (const Widge& rhs){ // 返回当前类的一个引用 5 // ... 6 return *this; // 返回*this给左边变量 7 } 8 // ... 9};
上面的这个规则对+=, -=, *=等复合运算符也同样适用。C++的内建数据类型,例如int, double,标准库的类型(例如std::string, std::complex),它们的赋值运算符也遵循上述规则。
1class Widge{ 2public: 3 // ... 4 Widge& operator+= (const Widge& rhs){ // 上述规则对复合运算符+=也适合 5 // ... 6 return *this; 7 } 8 // ... 9 10 Widge& operator=(int rhs){ // 上述规则对内建数据类型也适合 11 // ... 12 return *this; 13 } 14 // ... 15};
3.总结
(1) 赋值运算符应返回一个指向*this的引用。