-> arrow operator
参考资料
- stackoverflow
- Thinking in C++ 12.3.4.2 ~ 12.3.4.4
stackoverflow 最高票翻译
- ->
它必须被定义为非静态成员函数(原因是需要this指针), 且没有参数. 它的返回值 被用来 调用 该返回值的成员
如果该返回值是另一个类类型, 而非指针, 那么就会继续调用该类类型的operator->函数. 这种行为被称为"drill-down behavior". 直到最后一个返回的是指针为止.
struct client
{ int a; };
struct proxy {
client *target;
client *operator->() const
{ return target; }
};
struct proxy2 {
proxy *target;
proxy &operator->() const
{ return * target; }
};
void f() {
client x = { 3 };
proxy y = { & x };
proxy2 z = { & y };
std::cout << x.a << y->a << z->a; // print "333"
}
->* .* 和 .
->*
这个运算符并不特殊,和普通的二目运算符相似, 也没有必须为非静态成员的限制.
若为非静态成员, 参考Thinking in c++ , 专门为类设计了存放函数的类. 该类是一个类函数, ->* 在返回处 调用它的构造函数, 执行时会把目标函数的参数传给该类的迭代器的operator().* 和 .
这两个不能重载
#include <iostream>
using namespace std;
class AB {
public:
int a;
int b;
typedef void (AB::*action)() const;
AB():a(1),b(2){}
AB(const int&x, const int &y):a(x),b(y){}
void func_1() const {
cout <<"AB::func_1()"<<endl;
}
void func_2() const {
cout <<"AB::func_2()"<<endl;
}
};
class ABset {
typedef AB* ABP;
AB ab[20];
public:
friend class absiterator;
typedef class absiterator iterator;
ABset(){
for(int i=0;i<20;i++){
ab[i].a = i;
ab[i].b = i*2;
}
}
ABP begin(){
return &(ab[0]);
}
};
class absiterator {
typedef AB& ABRef;
typedef AB* ABP;
typedef AB::action ABACT;
typedef ABP & ABPRef;
typedef absiterator __Self;
ABP abptr;
public:
absiterator(ABP abp):abptr(abp){}
absiterator():abptr(NULL){}
ABRef operator*(){
return *abptr;
}
ABP operator->(){
return abptr;
}
ABPRef operator=(AB *abp){
abptr = abp;
return abptr;
}
ABPRef operator+(int n){
abptr += n;
return abptr;
}
};
struct Dog{
Dog(){cout <<"\nDog()"<<endl;}
int run(int a){
cout <<"run "<<a<<endl;
return a;
}
int sleep(int b){
cout <<"sleep "<<b<<endl;
return b;
}
int eat(int c){
cout <<"eat "<<c<<endl;
return c;
}
typedef int (Dog::*action)(int);
class FuncIter {
Dog* ptr;
Dog::action act;
public:
FuncIter(Dog* wp, action ai): ptr(wp), act(ai) {
cout <<"construction FuncIter"<<endl;
}
int operator()(int a){
cout <<"operator()"<<endl;
return (ptr->*act)(a);
}
};
class FuncIter operator->*(action ai){
cout <<"operator->*"<<endl;
return FuncIter(this,ai);
}
};
int main ()
{
ABset ax;
ABset::iterator ai = ax.begin();
//AB::action act = &AB::func_2;
ai = ai+2;
cout <<ai->a<<endl;
cout <<(*ai).b<<endl;
ai->func_1();
Dog dg;
Dog::action dact = &Dog::run;
(dg->*dact)(3);
return 0;
}