1樓:燈火不滅
採用取成員函式指標的位址的方法,先把指向成員函式指標的指標強制轉化為別的型別,如unsigned*,當然同樣可以通過此轉化後的指標經過相反的變換來呼叫成員函式。於是乎要轉化為void*的問題也隨之可解,如下示例:
/* VS2003下編譯執行 */
class AbstractMethodvoid fun1()};int main(){// 定義成員函式指標型別
typedef void (AbstractMethod::*MFP)(void);
// 轉化函式指標為別的指標
MFP mfp1 = &AbstractMethod::show;
unsigned* tmp = (unsigned*)&mfp1;
cout << hex << *tmp << endl;
MFP mfp2 = &AbstractMethod::fun;
tmp = (unsigned*)&mfp2;
cout << hex << *tmp << endl;
MFP mfp3 = &AbstractMethod::fun1;
tmp = (unsigned*)&mfp3;
cout << hex << *tmp << endl;
// 通過轉化後的指標呼叫成員函式
AbstractMethod am;
MFP* addr = (MFP*)tmp;
(am.*mfp3)();
1. 在除錯是檢視臨時變數函式指標的值和輸出的是否一樣。
2. 可以根據除錯時的反彙編進行結果驗證。
3. 最好的辦法就是如上例子通過轉化後的指標來呼叫成員函式。
2樓:舊巷裡的貓語
好像報錯這兩種型別是不匹配的。
void (Form::*_ptr)();
void (MainForm::* func)();
給他強制轉換一下:
typedef void (Form::*_ptr)();
c.setPtr( (func)&MainForm::f );
但是還是不明白你這樣做的目的何在。呼叫另外乙個類的成員函式,為什麼不通過物件呢?或者靜態成員函式也行啊!要不然宣告control是MainForm的友元類。
在你原來的Control類的exec函式處理的有問題:
void exe()
Form* f; //f沒有被例項化,呼叫成員函式_ptr就會報錯。它指向的是無效位址
(f->*_ptr)();
我這樣修改了下:Control接收到事件時(比如button被按下)它可以將這個訊息傳遞給MainForm,由MainForm來判斷並決定怎麼做,而不是把MainForm的成員函式預先設定到Control裡面。這樣我覺得比函式指標要好理解些。
對每個Control設定它的parent,事件發生時,就呼叫parent的handleEvent函式。這裡就是MainForm的handleEvent了。再在裡面根據sender和message來呼叫不同的成員函式。
class Control;
class Form;
class MainForm;
class Form
public:
virtual void handleEvent(int sender, int message) = 0;
class Control
public:
void exe()
parent->handleEvent(1,1);
Form * parent;
void setParent( Form *form )
parent = form;
class MainForm : public Form
public:
Control c;
void f()
cout<<"MainForm::f()"<<endl;
void handleEvent(int sender, int message)
// handle event
if(sender == 1 && message == 1)
f();
void init()
c.setParent(this );
3樓:我不姓胡
蝦公尺意思?是指類的成員變數是否可以指向類中的成員函式嗎?如果這樣子的,類的成員函式指標就是用來起這個作用,mfc訊息路由機制也是機遇此原理。
#include <stdio.h>class A
public:
A() // Ctor
m_pfn1 = A::foo; // 有沒有取位址符號一樣m_pfn2 = &A::bar; (this->*m_pfn1)();
(this->*m_pfn2)(0);
} void foo()
void (A::*m_pfn1)(); // 類函式指標成員變數void (A::*m_pfn2)(int); // 類函式指標成員變數};int _tmain(int argc, _TCHAR* argv)
// 1. 類函式指標成員變數的使用
A a;
A* p = &a;
(a.*(a.m_pfn1))();
(a.*(a.m_pfn2))(0); // 多型(p->*(p->m_pfn1))();
(p->*(p->m_pfn2))(0); // 多型// 2. 類外函式指標變數的使用
typedef void (A::*MemFunPtr)();
MemFunPtr memPtr = &A::foo;
(a.*memPtr)();
(p->*memPtr)(); return 0;
4樓:Cytosine
在 C++ 中,因為 this 指標作為隱含的引數並沒有出現在成員函式的宣告中,導致了實際編譯生成的函式與成員函式宣告的函式簽名並不相同,所以成員函式並不存在函式指標,只能使用成員函式指標。
成員函式的型別宣告與普通函式型別宣告的差距是增加了乙個型別名:
/// 函式指標
template
Ret, class ...Args >usingFn= Ret(*)( Args ...); /// 成員函式指標 template Ret, class Class ,class ...Args >using MemFn =Ret (Class ::*)( Args ...); /// 常量成員函式 template Ret, class Class ,class ...Args >using ConstMemFn =Ret (Class ::*)( Args ...) const ;如果想要獲得成員函式指標,那麼同樣也需要增加型別名: voidfn( int) {}class Avoidfn( int) const {}}; /// 函式指標 void(* fn_ptr1 )(int)= &fn;/// 使用型別別名 Fn ,int >fn_ptr2=& fn;/// 顯示宣告型別 void(A ::*mem_fn1 )(int)= &A::fn ;void(A ::*const_mem_fn1 )(int )const=& A::fn; /// 使用型別別名 MemFn ,int >mem_fn2=& A::fn; ConstMemFn ,int >const_mem_fn2=& A::fn; /// 通過 static_cast 提供型別 auto mem_fn3 =static_cast ::*)( int) >(&A:: fn); auto const_mem_fn3 =static_cast ::*)( int) const >(&A:: fn); 注意對於有同名成員函式的情況,必須提供型別,否則編譯器無法確定應該選擇哪個函式。 如果需要呼叫成員函式指標,也需要使用特殊的語法:Aa1 {};constAa2 {};A *a1_ptr=& a1;constA* a2_ptr=& a2;/// 直接呼叫成員函式指標(a1 .*mem_fn1)(0 );(a2. *const_mem_fn1)(0 );/// 通過指標呼叫成員函式指標 (a1_ptr ->*mem_fn1)(0 );(a2_ptr ->*const_mem_fn1)(0 );但是,成員函式指標仍舊會帶來很多問題,成員函式指標並非平凡的指標,在不同的編譯器下有不同的實現方法,在不同的情況下會有不同的大小。 如何獲得函式指標,又不需要每次都寫乙個對應的靜態成員函式呢?我們可以定義以下模版: #include // std::forward template Ff>struct ;template Class ,class Ret, class ...Args ,Ret (Class ::*f )(Args ...) const >struct Class ::*)( Args ...) const,f >};template Class ,class Ret, class ...Args ,Ret (Class ::*f )(Args ...) >struct Class ::*)( Args ...), f>};之後,我們就可以直接獲取函式指標了: Fn *,int> mem_fn4=& ::*)( int),&A ::fn >:: inner;Fn ,constA* ,int >const_mem_fn4=& ::*)( int) const,& A::fn>:: inner; 5樓:C十十20年 幹嘛寫高度依賴編譯器的東西,如果有虛析構函式怎麼辦?有的編譯器把this壓棧,而VC編譯器則是把this放在ecx。所以,對VC來說f(a)這個方法不會成功,因為a被視為this但作為實參壓棧了,而ⅤC編譯器只從ecx取出this。 因此,使用(a->*f)( )才能把a作為this送入ecx,此時f的型別應該定義為int (Base::*)( )才能使用(a->*f)( )。參見《C++程式設計精要教程》之型別解析與有虛析構函式時的物件記憶體布局。 BinGostar 將bar函式改為如下 void bar test pp tkzzz 可以定義乙個函式指標第乙個引數是void 然後傳遞的時候第乙個引數就是類位址因為在cpp裡面類成員函式的呼叫就是第乙個引數是類位址 具體如下 include template F void f2a F f fun... zr scat 瀉藥先定義乙個函式指標 typedef void pfn void 再定義指向函式指標的指標 void print void pfn func print pfn ptr func 在c 11下,可以這麼偷懶獲得型別 1 include 23using namespace std 4... 很多微控制器程式是不依賴庫的,它們會有中斷呼叫。很多微控制器的編譯器是用GCC。既然問題又提到MSVC,就意味著Windows程式,不依賴庫是不行的,因為作業系統已經將軟硬體隔離,任何呼叫都需要經過作業系統一層,可以寫出看不到依賴庫的程式 方法是從 Process Envirorment Block...C 如何將成員函式指標作為普通函式的引數傳遞?
C 中如何定義指向函式指標的指標?
關於C語言, GCC MSVC中,如何寫出乙個真正意義上的不依賴庫的程式?