在得到this questionçš„ç”案åŽï¼Œæˆ‘å‘现有两ç§æœ‰æ•ˆçš„方法å¯ä»¥è¾“入定义函数指针。
typedef void (Function) ();
typedef void (*PFunction) ();
void foo () {}
Function * p = foo;
PFunction q = foo;
我现在更喜欢Function * p
到PFunction q
,但显然这对指针到æˆå‘˜å‡½æ•°ä¸èµ·ä½œç”¨ã€‚考虑这个人为的例å。
#include <iostream>
struct Base {
typedef void (Base :: *Callback) ();
//^^^ remove this '*' and put it below (i.e. *cb)
Callback cb;
void go () {
(this->*cb) ();
}
virtual void x () = 0;
Base () {
cb = &Base::x;
}
};
struct D1 : public Base {
void x () {
std :: cout << "D1\n";
}
};
struct D2 : public Base {
void x () {
std :: cout << "D2\n";
}
};
int main () {
D1 d1;
D2 d2;
d1 .go ();
d2 .go ();
}
ä½†å¦‚æžœæˆ‘å°†å…¶æ›´æ”¹ä¸ºæ–°çš„é¦–é€‰æ ·å¼ï¼štypedef void (Base :: Callback) ()
å’ŒCallback * cb
,我会在typedef
 Âæˆå‘˜'回调'上的é¢å¤–èµ„æ ¼'Base ::'
为什么ä¸å…è®¸è¿™æ ·åšï¼Ÿè¿™åªæ˜¯ä¸€ç§ç–忽还是会导致问题?
ç”案 0 :(得分:10)
对于éžæˆå‘˜å‡½æ•°ï¼Œtypedef void(Function)()
ç‰ç±»åž‹æœ‰å¤šç§ç”¨é€”,但对于æˆå‘˜å‡½æ•°ï¼Œå”¯ä¸€çš„应用是声明一个包å«å‡½æ•°æŒ‡é’ˆçš„å˜é‡ã€‚å› æ¤ï¼Œé™¤äº†é£Žæ ¼åå¥½ä¹‹å¤–ï¼Œæ²¡æœ‰ä¸¥æ ¼çš„éœ€è¦å…许这ç§è¯æ³•ï¼Œå¹¶ä¸”å®ƒå·²ä»Žæ ‡å‡†ä¸çœç•¥ã€‚
::
是作用域解æžè¿ç®—符,如果X::Y
是类类型,则è¯æ³•static
ä¿ç•™ç”¨äºŽX
æˆå‘˜è®¿é—®ã€‚å› æ¤ï¼ŒX::*Z
是å¦ä¸€ç§ç”¨äºŽå®šä¹‰æŒ‡å‘æˆå‘˜æŒ‡é’ˆçš„è¯æ³•ã€‚
忘记æˆå‘˜å‡½æ•°ä¸€æ®µæ—¶é—´ï¼Œåªè¦æƒ³ä¸€æƒ³ member-data ,看看这段代ç :
struct X
{
int a;
};
int X::*pa = &X::a; //pointer-to-member
X x = {100}; //a = 100
cout << (x.*pa) << endl;
它定义了一个指å‘æˆå‘˜æ•°æ®çš„指针,而cout
使用它æ¥æ‰“å°å¯¹è±¡a
çš„{​​{1}}的值,它打å°ï¼š
x
演示:http://www.ideone.com/De2H1
现在想想,如果100
(而ä¸æ˜¯X::pa
)被å…è®¸è¿™æ ·åšï¼Œé‚£ä¹ˆä½ å·²ç»å°†ä¸Šè¿°å†…容写æˆï¼š
X::*pa
看到这ç§è¯æ³•ï¼Œæ‚¨å¦‚何判æ–int X::pa = X::a; //not &X::a
是X::a
æˆå‘˜è¿˜æ˜¯éžé™æ€æˆå‘˜ï¼Ÿè¿™å°±æ˜¯æ ‡å‡†æ出指å‘æˆå‘˜æŒ‡é’ˆè¯æ³•çš„ä¸€ä¸ªåŽŸå› ï¼Œå¹¶å°†å…¶ç»Ÿä¸€åº”ç”¨äºŽéžé™æ€æˆå‘˜æ•°æ®ä»¥åŠéžé™æ€æˆå‘˜å‡½æ•°ã€‚
äº‹å®žä¸Šï¼Œæ‚¨æ— æ³•æ’°å†™static
,您需è¦æ’°å†™X::a
。è¯æ³•&X::a
会导致编译错误(请å‚阅this)。
现在将 member-data 的这个å‚数扩展到 member-function 。å‡è®¾ä½ 有一个typedef定义为:
X::a
那么您认为以下代ç 是åšä»€ä¹ˆçš„?
typedef void fun();
好å§ï¼Œå®ƒå®šä¹‰ç±»åž‹struct X
{
fun a;
};
çš„æˆå‘˜a
(函数ä¸å¸¦å‚数,返回void),并且相当于:
fun
惊讶?请继ç»é˜…读。
struct X
{
void a();
};
我们å¯ä»¥ä½¿ç”¨å®Œå…¨ç›¸åŒçš„è¯æ³•æ¥å¼•ç”¨çŽ°åœ¨æ˜¯æˆå‘˜å‡½æ•°çš„struct X
{
fun a; //equivalent to this: void a();
};
void X::a() //yes, you can do this!
{
cout << "haha" << endl;
}
:
a
相似性是å³ä¾§çš„synatax:X x;
x.a(); //normal function call
void (X::*pa)() = &X::a; //pointer-to-member
(x.*pa)(); //using pointer-to-member
。 &X::a
是指æˆå‘˜å‡½æ•°è¿˜æ˜¯æˆå‘˜æ•°æ®ï¼Œè¯æ³•æ˜¯ç›¸åŒçš„。
演示:http://www.ideone.com/Y80Mf
<强>结论:强>
我们知é“æ— è®ºa
是æˆå‘˜æ•°æ®è¿˜æ˜¯æˆå‘˜å‡½æ•°ï¼Œæˆ‘ä»¬éƒ½æ— æ³•åœ¨RHS上编写X::a
。唯一å…许的è¯æ³•æ˜¯a
ï¼Œè¿™ä½¿å¾—ç›®æ ‡ç±»åž‹ï¼ˆåœ¨LHS上)必须也必须是指针,这å过æ¥ä½¿è¯æ³•&X::f
ç»å¯¹å¿…è¦å’ŒåŸºç¡€ï¼Œå› 为它符åˆè¯è¨€ä¸çš„其他è¯æ³•ã€‚
ç”案 1 :(得分:2)
准确地说,éžæˆå‘˜æŒ‡é’ˆçš„两个typedef是ä¸ä¸€æ ·çš„:
typedef void function();
typedef void (*fptr)();
第一个将function
定义为ä¸å¸¦å‚数的函数并返回void
,而第二个将ftpr
定义为函数获å–的指针没有å‚数并返回void
。由于函数类型将在许多上下文ä¸éšå¼è½¬æ¢ä¸ºæŒ‡é’ˆç±»åž‹ï¼Œå› æ¤å¯èƒ½ä¼šäº§ç”Ÿæ··æ·†ã€‚但ä¸æ˜¯å…¨éƒ¨ï¼š
function f; // declares void f();
struct test {
function f; // declares void test::f()
};
void g( function f ); // declares g( void (*f)() ): function decays to pointer to function in declaration
g( f ); // calls g( &f ): function decays to pointer to function
void f() {} // definition of f
// function h = f; // error: cannot assign functions
function *h = f; // f decays to &f
ç”案 2 :(得分:0)
让我们跳过“功能â€éƒ¨åˆ†ä¸€ç§’钟。在C ++ä¸ï¼Œæˆ‘们有int
,int*
å’Œint Foo::*
类型。这是一个常规整数,指å‘整数的指针,以åŠæŒ‡å‘æ•´æ•°æˆå‘˜çš„指针。没有第四ç§ç±»åž‹çš„“整数æˆå‘˜â€ã€‚
完全相åŒçš„函数:å³ä½¿æœ‰å‡½æ•°ç±»åž‹ï¼Œå‡½æ•°æŒ‡é’ˆç±»åž‹å’Œæˆå‘˜å‡½æ•°æŒ‡é’ˆç±»åž‹ï¼Œä¹Ÿæ²¡æœ‰ç±»åž‹â€œæˆå‘˜å‡½æ•°â€ã€‚