程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 在C++類中定義線程函數的方法

在C++類中定義線程函數的方法

編輯:C++入門知識

昨天用C++把我寫的一個游戲功能進行了封裝,其中涉及到一個小問題,就是我封裝的C++類中必須定義2個線程函數,比如像下面這樣:
1. class A 
2. { 
3. public: 
4.     A(); 
5.     ~A(); 
6.  
7.     void XXX(void *p);   //此函數為線程回調函數 
8. }; 
其中XXX為線程回調函數,在另一個線程啟動函數中需要用_beginthread()這個函數來調用的。但是當我在這麼寫時:
_beginthread(XXX, 0, NULL);
編譯器報錯誤。。也就是無法編譯通過。我仔細想了想,覺得確實也無法編譯通過,因為線程函數在編譯的時候必須知道函數入口地址才行,而我這麼寫,XXX的入口地址確實還是未知的。。
所以我想到了兩種把未知變為已知的方法,一種是把XXX定義成靜態成員函數,如下:
static void XXX(void *p);
另一種是把XXX定義成全局函數。
其實是一個道理,就是為了讓_beginthread()知道這個函數的入口地址,全局函數和靜態函數都存放在一個地方,在編譯時都是已知的。
當我以為一切OK的時候,發現在XXX()函數中又報錯了。。
說我使用了不在類域中的成員。其實就是這麼個意思:
1. class A  
2. {  
3. public:  
4.     A();  
5.     ~A();  
6.   
7.     static void XXX(void *p);   //此函數為線程回調函數www.2cto.com
8. 
9.     int a;   //在XXX函數中會進行修改
10. }; 
其中A的成員變量a會在XXX()函數中進行修改,而在XXX函數中其實是看不到這個成員的。
你也許會問,怎麼就看不到呢?我平時就是這麼寫的啊。比如我在A中定義的其他成員函數就可以直接訪問這個a啊。
確實,在類A中其他的一般成員函數是可以訪問這個成員變量a的。但是我們很容易忽略了一點,就是在一般成員函數中其實有一個隱藏的參數,就是指向這個類的this指針,我們在成員函數中訪問成員變量a,其實是在訪問this->a。所以我們的成員函數能夠找到這個a,而我們的線程函數卻沒有傳遞這個參數,XXX()是用_beginthread()函數來創建的,所以如果我們要給XXX()傳遞參數,就必須寫在_beginthread()的第三個參數中,可以看到我上面寫的第三個參數是NULL,所以在XXX()中是無法訪問成員變量a的,因為沒有this指針。
明白這一點以後就非常容易了,在_beginthread()中把this指針傳遞給XXX()函數,然後在XXX()函數中把void*類型轉換成類A的指針就可以了。如下:
1. class A   
2. {   
3. public:   
4.     A();   
5.     ~A();   
6.    
7.     static void XXX(void *p);   //此函數為線程回調函數 
8.     void start();   //線程啟動函數 
9.     int a;   //在XXX函數中會進行修改 
10. }; 
11. 
12. void start()
13. {
14.     _beginthread(XXX, 0, this);
15. }
16. 
17. void XXX(void *p)
18. {
19.     A *handle = (A *)p;
20.     int b = handle->a;
21. }
我是不是很牛。。。呵呵。好吧,我泛濫了。

 摘自 菜鳥浮出水
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved