A. 如何在回調函數中調用某個類的成員函數
如果試圖直接使用C++的成員函數作為回調函數將發生錯誤,甚至編譯就不能通過。
其錯誤是普通的C++成員函數都隱含了一個傳
多個實例可以共享成員函數卻-有不同的數據成員。由於this指針的作用,使得將一個CALL-BACK型的成員函數作為回調函數安裝時就會因為隱含的
this指針使得函數參數個數不匹配,從而導致回調函數安裝失敗。要解決這一問題的關鍵就是不讓this指針起作用,通過採用以下兩種典型技術可以
解決在C++中使用回調函數所遇到的問題。這種方法具有通用性,適合於任何C++。
1). 不使用成員函數,為了訪問類的成員變數,可以使用友元操作符(friend),在C++中將該函數說明為類的友元即可。
2). 使用靜態成員函數,靜態成員函數不使用this指針作為隱含參數,這樣就可以作為回調函數了。靜態成員函數具有兩大特點:其一,可以
在沒有類實例的情況下使用;其二,只能訪問靜態成員變數和靜態成員函數,不能訪問非靜態成員變數和非靜態成員函數。由於在C++中使用類成員
函數作為回調函數的目的就是為了訪問所有的成員變數和成員函數,如果做不到這一點將不具有實際意義。解決的辦法也很簡單,就是使用一個靜態
類指針作為類成員,通過在類創建時初始化該靜態指針,如pThis=this,然後在回調函數中通過該靜態指針就可以訪問所有成員變數和成員函數了。
這種處理辦法適用於只有一個類實例的情況,因為多個類實例將共享靜態類成員和靜態成員函數,這就導致靜態指針指向最後創建的類實例。為了避
免這種情況,可以使用回調函數的一個參數來傳遞this指針,從而實現數據成員共享。這種方法稍稍麻煩,這里就不再贅述。
例子:#include"stdafx.h"#include<iostream#include<assert.husingnamespacestd;classTest{public:friendvoidcallBackFun(void){ cout<<"CallBack Function!";}//因為callBackFun默認有一個const Test* 的指針};typedefvoid(*FPtr)(void);voidFun(FPtr ptr){ptr();}intmain(void){Fun(callBackFun);return0;}原文請訪問:
B. 編寫find函數,在一維數組x中查找是否有key,若有返回該數組元素下標,否
代碼:
intfind(int*a,intn,intx)
{
inti;
for(i=0;i<n;++i)
if(a[i]==x)
returni;
return-1;
}
intmain()
{
inta[10],x,i;
printf("input10number:");
for(i=0;i<10;++i)
scanf("%d",a+i);
printf("inputnumbertofind:");
scanf("%d",&x);
i=find(a,10,x);
if(i>0)
printf("find%dforindex%d ",x,i);
else
printf("notind%dinarray ",x);
return0;
}
C. 回調函數是怎麼實現的為什麼系統就會去調用回調函數
回調函數是應用程序提供給Windows系統DLL或其它DLL調用的函數,一般用於截獲消息、獲取系統信息或處理非同步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵守事先規定好的參數格式和傳遞方式,否則DLL一調用它就會引起程序或系統的崩潰。通常情況下,回調函數採用標准WindowsAPI的調用方式,即__stdcall,當然,DLL編制者可以自已定義調用方式,但客戶程序也必須遵守相同的規定。在__stdcall方式下,函數的參數按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數都按值傳遞,函數返回之前自己負責把參數從堆棧中彈出。 程序在調用一個函數(function)時(通常指api).相當於程序(program)呼叫(Call)了一個函數(function)關系表示如下: call(調用) program --------------------→ dll 程序在調用一個函數時,將自己的函數的地址作為參數傳遞給程序調用的函數時(那麼這個自己的函數稱回調函數).需要回調函數的 DLL 函數往往是一些必須重復執行某些操作的函數.關系表示如下: call(調用) program --------------------→ dll ↑ ¦ ¦_______________________________¦ callback(回調) 當你調用的函數在傳遞返回值給回調函數時,你就可以利用回調函數來處理或完成一定的操作。至於如何定義自己的回調函數,跟具體使用的API函數有關,很多不同類別的回調函數有各種各樣的參數,有關這些參數的描述一般在幫助中有說明回調函數的參數和返回值等.其實簡單說回調函數就是你所寫的函數滿足一定條件後,被DLL調用! Windows 系統還包含著另一種更為廣泛的回調機制,即消息機制。消息本是 Windows 的基本控制手段,是一種變相的函數調用。發送消息的目的是通知收方運行一段預先准備好的代碼,相當於調用一個函數。消息所附帶的 WParam 和 LParam 相當於函數的參數,應用程序可以主動發送消息,更多情況下是坐等 Windows 發送消息。一旦消息進入所屬消息隊列,便檢感興趣的那些,跳轉去執行相應的消息處理代碼。操作系統本是為應用程序服務,由應用程序來調用。而應用程序一旦啟動,卻要反過來等待操作系統的調用。這分明也是一種回調,或者說是一種廣義回調。其實,應用程序之間也可以形成這種回調。假如進程 B 收到進程 A 發來的消息,啟動了一段代碼,其中又向進程 A 發送消息,這就形成了回調。這種回調比較隱蔽,弄不好會搞成遞歸調用,若缺少終止條件,將會循環不已,直至把程序搞垮。利用消息也可以構成狹義回調。把回調函數地址換成窗口 handle。如此,當需要比較數據大小時,不是去調用回調函數,而是借 API 函數 SendMessage 向指定窗口發送消息。收到消息方負責比較數據大小,把比較結果通過消息本身的返回值傳給消息發送方。所實現的功能與回調函數並無不同。當然,此例中改為消息純屬畫蛇添腳,反倒把程序搞得很慢。但其他情況下並非總是如此,特別是需要非同步調用時,發送消息是一種不錯的選擇。假如回調函數中包含文件處理之類的低速處理,調用方等不得,需要把同步調用改為非同步調用,去啟動一個單獨的線程,然後馬上執行後續代碼,其餘的事讓線程慢慢去做。一個替代辦法是借 API 函數 PostMessage 發送一個非同步消息,然後立即執行後續代碼。這要比自己搞個線程省事許多,而且更安全。 只要與編程有關,無論何事都離不開 object。但 object 並未消除回調,反而把它發揚光大,弄得到處都是,只不過大都以事件(event)的身份出現,鑲嵌在某個結構之中,顯得更正統,更容易被人接受。應用程序要使用某個構件,總要先弄清構件的屬性、方法和事件,然後給構件屬性賦值,在適當的時候調用適當的構件方法,還要給事件編寫處理常式,以備構件代碼來調用。何謂事件?它不過是一個指向事件常式的地址,與回調函數地址沒什麼區別。不過,此種回調方式比傳統回調函數要高明許多。首先,它把讓人不太舒服的回調函數變成一種自然而然的處理常式,使編程者頓覺氣順。再者,地址是一個危險的東西,用好了可使程序加速,用不好處處是陷阱,程序隨時都會崩潰。現代編程方式總是想法把地址隱藏起來(隱藏比較徹底的如 VB 和 Java),其代價是降低了程序效率。事件常式(?)使編程者無需直接操作地址,但並不會使程序減速。 回調用於層間協作,上層將本層函數安裝在下層,這個函數就是回調,而下層在一定條件下觸發回調,例如作為一個驅動,是一個底層,他在收到一個數據時,除了完成本層的處理工作外,還將進行回調,將這個數據交給上層應用層來做進一步處理,這在分層的數據通信中很普遍。其實回調和API非常接近,他們的共性都是跨層調用的函數。但區別是API是低層提供給高層的調用,一般這個函數對高層都是已知的;而回調正好相反,他是高層提供給底層的調用,對於低層他是未知的,必須由高層進行安裝,這個安裝函數其實就是一個低層提供的API,安裝後低層不知道這個回調的名字,但它通過一個函數指針來保存這個回調,在需要調用時,只需引用這個函數指針和相關的參數指針。 其實:回調就是該函數寫在高層,低層通過一個函數指針保存這個函數,在某個事件的觸發下,低層通過該函數指針調用高層那個函數。 軟體模塊之間總是存在著一定的介面,從調用方式上,可以把他們分為三類:同步調用、回調和非同步調用。同步調用是一種阻塞式調用,調用方要等待對方執行完畢才返回,它是一種單向調用;回調是一種雙向調用模式,也就是說,被調用方在介面被調用時也會調用對方的介面;非同步調用是一種類似消息或事件的機制,不過它的調用方向剛好相反,介面的服務在收到某種訊息或發生某種事件時,會主動通知客戶方(即調用客戶方的介面)。回調和非同步調用的關系非常緊密,通常我們使用回調來實現非同步消息的注冊,通過非同步調用來實現消息的通知。同步調用是三者當中最簡單的,而回調又常常是非同步調用的基礎。 對於不同類型的語言(如結構化語言和對象語言)、平台(Win32、JDK)或構架(CORBA、DCOM、WebService),客戶和服務的交互除了同步方式以外,都需要具備一定的非同步通知機制,讓服務方(或介面提供方)在某些情況下能夠主動通知客戶,而回調是實現非同步的一個最簡捷的途徑。 對於一般的結構化語言,可以通過回調函數來實現回調。回調函數也是一個函數或過程,不過它是一個由調用方自己實現,供被調用方使用的特殊函數。在面向對象的語言中,回調則是通過介面或抽象類來實現的,我們把實現這種介面的類成為回調類,回調類的對象成為回調對象。對於象C++或Object Pascal這些兼容了過程特性的對象語言,不僅提供了回調對象、回調方法等特性,也能兼容過程語言的回調函數機制。 Windows平台的消息機制也可以看作是回調的一種應用,我們通過系統提供的介面注冊消息處理函數(即回調函數),從而實現接收、處理消息的目的。由於Windows平台的API是用C語言來構建的,我們可以認為它也是回調函數的一個特例。 對於分布式組件代理體系CORBA,非同步處理有多種方式,如回調、事件服務、通知服務等。事件服務和通知服務是CORBA用來處理非同步消息的標准服務,他們主要負責消息的處理、派發、維護等工作。對一些簡單的非同步處理過程,我們可以通過回調機制來實現。
D. C語言的回調函數怎麼用,請幫忙舉例說明
看一下這個例子吧,我是這樣理解的:
#include
"iostream.h"
#include
"windows.h"
typedef
void
(CALLBACK
*MyFun)(void);//回調函數定義
void
CALLBACK
callback()
//
回調函數
{
cout<<"****callback****\n";
}
void
Call_CallBack(MyFun
mycb)
{
cout<<"****Call_CallBack****\n";
mycb();
cout<<"__________________\n";
}
void
main()
{
Call_CallBack(callback);
}
//
其他人需要修專改的話只要修改callback函數里屬的內容就行了,一般sdk封裝後都會有回調,這樣他人在調用sdk的時候就可以實現回調函數里的內容。
如果你需要理論的,網上搜回調函數,內容哈多隨便看
E. 求救C++編程實現findmax函數
最簡單的方法:
調用STL的Algorithm的max_element方法。
template <class ForwardIterator>
ForwardIterator max_element ( ForwardIterator first, ForwardIterator last );
template <class ForwardIterator, class Compare>
ForwardIterator max_element ( ForwardIterator first, ForwardIterator last,
Compare comp );
實現方法:
template <class ForwardIterator>
ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
ForwardIterator largest = first;
if (first==last) return last;
while (++first!=last)
if (*largest<*first) // or: if (comp(*largest,*lowest)) for the comp version
largest=first;
return largest;
}
你只要實例化模板就可以了。
F. C語言中的回調函數使用情況
Search_List 函數 的第二個 參數 是 函數指針
在Search_List函數內 利用這個指針 去調回用被傳入的另答一個函數
if (compare((node->value_address), desired_value) == 0) 就是 則個if 里的
G. Windows程序設計主窗口過程怎麼調用回調函數的子窗口,或者說怎麼調用回調函數
先在窗口注冊目標窗口的回調函數ParentProc:
// Set parent window original processing.
m_OriParentProc = ::GetWindowLong(m_hParentWnd, GWL_WNDPROC);
::SetWindowLong(m_hParentWnd, GWL_WNDPROC, (LONG)ParentProc);
然後定義回調函數ParentProc,就可以接受目標窗口的所有窗口消息了:
static LRESULT CALLBACK ParentProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Find the shadow window pointer via parent window handle.
ATLASSERT( m_szShadowWindows.find(hwnd) != m_szShadowWindows.end() );
CThemedShadowWnd *pThis = m_szShadowWindows[hwnd];
WNDPROC pDefProc = (WNDPROC)pThis->m_OriParentProc;
switch(uMsg)
{
case WM_DESTROY:
{
// Destroy the shadow window.
pThis->DestroyWindow();
break;
}
default:
{
if (::IsWindowVisible(hwnd))
{
pThis->AdjustWindowPos();
}
break;
}
}
return pDefProc(hwnd, uMsg, wParam, lParam);
}
H. VB 編程,使用FindWindow 每次返回的結果都不同且不為0
這個我還真不會 apia不熟
I. 回調函數的用法請舉例
我理解的回調函數就是將一個回調函數(固定的輸入參數個數與類型)的指針交給操作系統版,
當滿足回調函數的權調用條件時操作系統會自動調用回調函數,並將參數傳入回調函數
我們一般的程序按自已的流程走,一般用不到回調,但要響應事件時就要用到回調函數
因為不能像在DOS中那輪詢事件是否發生,只能靠操作系統在發出事件時調用事件的處理函數
J. C語言編程問題:編寫一個函數intFindmax(float a[],int n),查找大小為n的實型數組a中的最大數
#include <stdio.h>
void Findmax(float a[])
{
int i,m=0;
for(i=0;i<100;i++)
{
if(a[i]>a[m])
m=i;
}
printf("%f,%d",a[m],m);
}
void main()
{
int i;
float A[100];
for(i=0;i<100;i++)
scanf("%f",A[i]);
Findmax(A);
}
Findmax函數中,for循環,數組下標要從0開始,參數n沒什麼用,在函數內定義版局部變數就可權以了
main函數,for循環讀入數組,要設退出條件,否則死循環了,局部變數n沒什麼用。