搞懂了C++的指针是吧?
那我随手列一点C++的指针出来看看你知不知道这是什么啊:
先来个基础版的:int (*p1)(float);
再来个C++版的:int (T::*p2)(float);
接着就稍微复杂点了:int (*(T::*p3)(float))(long);
懂了上面应该就能推导出来的:int (*T1::*(T2::*p4)(float))(long);
最后既然提到了数组,那就顺手加一个:int (*T1::*(T2::*p5[1])(float[0]))(long[]);
当然,这个实际上这是唬人的,大部分正常使用的时候,都不会这么写, 都是层层typedef的,看上去会清爽很多。但正常情况下,不说写,就说看,p3以上应该是要能看懂的。有p3作为基础,看懂p4也应该是ok的。
至于p5,那就随便了,看应该是不至于看不懂。主要是几个0长度数组、不定长数组的概念和使用等。
好像不少人看不明白,我就拿点代码解释一下吧:
int test(long) {return 1;} int func1(float) {return 0;}; struct T { int func2(float) {return 0;} auto func3(float) {return &test;} }; int (*p1)(float) = func1; int (T::*p2)(float) = &T::func2; int (*(T::*p3)(float))(long) = &T::func3;
p1、p2、p3应该是挺常规的,看代码就懂了。
p4实话说是写错了,本来没打算在T1前加那个*号的,那就是返回一个普通的类成员函数指针而已,确实应该是比较简单的。但我在拿了上面的p3下来改的时候手滑改错了……
结果,现在的p4实际上是这样的:
int test(long) {return 1;} struct T1 { int (*test2) (long) = &test; }; struct T2 { auto func4(float){return &T1::test2;} }; int (*T1::*(T2::*p4)(float))(long) = &T2::func4;
p4实际上是指向一个T2的成员函数(func4)的地址,而func4的返回类型是一个T1的函数指针类型(test)的成员变量(test2)的地址。
我不太能想得到这会有什么实际的用法,因为这玩意用起来很绕的:
T1 t1; T2 t2; std::cout << (t1.*(t2.*p4)(1.2))(10) << std::endl;
如果看不懂的话,分开两步写应该就好懂了:
auto pp = (t2.*p4)(1.2); std::cout << (t1.*pp)(10) << std::endl;
这是个意外,但似乎可以更生动的显示C++指针的复杂性:一点点的小变化,一不小心,老江湖也会被绕进去的。