运算符->的重载比较特别,它只能是非静态的成员函数形式,而且没有参数。
1、如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始指针所指向类型的成员进行访问;
2、如果返回值是另一个类型的实例,那么就继续调用这个返回类型的operator->(),直到有一个调用返回一个原始指针为止,然后按第一种情况处理。
如果上述条件不满足(如:右操作数不是返回的原始指针指向的类型中的成员,或者,返回的非指针类型(另一个类型的实例)没有重载operator->()),那么编译将报错。
以下是用于验证的程序片段:
/******************************************************* * File Name:main.cpp * Description:演示成员访问操作符->的重载 * Version:V1.0 * Author:Mengjia * Date:2018-05-20 * Copyright (C)2018, Mengjia * Others: ****************************************************************************** 运算符->的重载比较特别,它只能是非静态的成员函数形式(即不能在类外重载), 而且没有参数。 1、如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始 指针所指向类型的成员进行访问; 2、如果返回值是另一个类型的实例,那么就继续调用这个返回类型的operator->(),直到 有一个调用返回一个原始指针为止,然后就按第一种情况处理。 如果上述条件不满足(如:右操作数不是返回的原始指针指向的类型的成员,或者, 返回的另一个类型的实例中没有重载operator->()),那么编译将报错。 ****************************************************************************** *******************************************************/ #include <iostream> using namespace std; //原始类 struct Origin { int a; }; //包装器类1,包装Origin类 struct Wrapper { Origin* orig; Origin* operator->() const { return orig; //返回原始指针 } }; //包装器类2,包装Wrapper类 struct Wrapper2 { Wrapper* wrap; Wrapper& operator->() const { return *wrap; //返回类对象 } }; int main() { Origin o; o.a = 7; Wrapper w; w.orig = &o; Wrapper2 w2; w2.wrap = &w; cout << "w->a" << " " << w->a << endl; cout << "w.operator->()" << " " << w.operator->() << endl; cout << "w.operator->()->a" << " " << w.operator->()->a << endl; cout << "w2->a" << " " << w2->a << endl; cout << "&w2.operator->()" << " " << &w2.operator->() << endl; cout << "w2.operator->()->a" << " " << w2.operator->()->a << endl; cout << "w2.operator->().operator->()" << " " << w2.operator->().operator->() << endl; cout << "w2.operator->().operator->()->a" << " " << w2.operator->().operator->()->a << endl; system("pause"); return 0; } /* *输出结果: w->a 7 w.operator->() 00AFF7E4 w.operator->()->a 7 w2->a 7 &w2.operator->() 00AFF7D8 w2.operator->()->a 7 w2.operator->().operator->() 00AFF7E4 w2.operator->().operator->()->a 7 **/
其中,最为诡异的就是w2->a输出的是7。
按照上面总结的结论,这个调用其实会被编译器转换成w2.operator->().operator->()->a的形式,所以输出的是7。