VC6中,為什么只有類中的static成員函數,才可
系統
2066 0
VC6中,為什么只有類中的static成員函數,才可以做為線程啟動函數(ThreadProc)?
|
類中的static成員函數,存放在堆區吧?
類中的非靜態成員函數,也存放在堆區吧?
如果是,那么為什么會出現如題的現象呢?
|
|
|
回復內容
|
【an_bachelor】:
個人以為應該都放在代碼段
【haoranisme】:
堆區就存在代碼段吧?
那么,為什么只有類中的static成員函數,才可以做為線程啟動函數(ThreadProc)呢?
【laolaoliu2002】:
static是c++中很常用的修飾符,它被用來控制變量的存儲方式和可見性,下面我將從static修飾符的產生原因、作用談起,全面分析static修飾符的實質。
static的兩大作用:
一、控制存儲方式:
static被引入以告知編譯器,將變量存儲在程序的靜態存儲區而非棧上空間。
1、引出原因:函數內部定義的變量,在程序執行到它的定義處時,編譯器為它在棧上分配空間,大家知道,函數在棧上分配的空間在此函數執行結束時會釋放掉,這樣就產生了一個問題:如果想將函數中此變量的值保存至下一次調用時,如何實現?
最容易想到的方法是定義一個全局的變量,但定義為一個全局變量有許多缺點,最明顯的缺點是破壞了此變量的訪問范圍(使得在此函數中定義的變量,不僅僅受此函數控制)。
2、解決方案:因此c++中引入了static,用它來修飾變量,它能夠指示編譯器將此變量在程序的靜態存儲區分配空間保存,這樣即實現了目的,又使得此變量的存取范圍不變。
二、控制可見性與連接類型:
static還有一個作用,它會把變量的可見范圍限制在編譯單元中,使它成為一個內部連接,這時,它的反義詞為”extern”.
static作用分析總結:static總是使得變量或對象的存儲形式變成靜態存儲,連接方式變成內部連接,對于局部變量(已經是內部連接了),它僅改變其存儲方式;對于全局變量(已經是靜態存儲了),它僅改變其連接類型。
類中的static成員:
一、出現原因及作用:
1、需要在一個類的各個對象間交互,即需要一個數據對象為整個類而非某個對象服務。
2、同時又力求不破壞類的封裝性,即要求此成員隱藏在類的內部,對外不可見。
類的static成員滿足了上述的要求,因為它具有如下特征:有獨立的存儲區,屬于整個類。
二、注意:
1、對于靜態的數據成員,連接器會保證它擁有一個單一的外部定義。靜態數據成員按定義出現的先后順序依次初始化,注意靜態成員嵌套時,要保證所嵌套的成員已經初始化了。消除時的順序是初始化的反順序。
2、類的靜態成員函數是屬于整個類而非類的對象,所以它沒有this指針,這就導致了它僅能訪問類的靜態數據和靜態成員函數。
【laolaoliu2002】:
將成員函數聲明為靜態雖然可以解決作為線程函數的問題,但是它帶來了新的問題,那就是static成員函數只能訪問static成員。解決此問題的一種途徑是可以在調用類靜態成員函數(線程函數)時將this指針作為參數傳入,并在改線程函數中用強制類型轉換將this轉換成指向該類的指針,通過該指針訪問非靜態成員。
【haoranisme】:
學習了,但還是想知道:
為什么只有類中的static成員函數,才可以做為線程啟動函數(ThreadProc),
而類的非靜態成員函數不可以?
【gaooo】:
成員函數調用需this
【gaooo】:
非成員函數不需要this指針
【haoranisme】:
突然想到,會不會是為了區分代碼段和數據段呢?
【robinwjb】:
線程函數是獨立于類的實例而存在的,他的生命期不是類的生命期,而是整個process。
試想一下,如果可以用非靜態成員函數作為線程函數,如果沒有定義一個這個類的實例,
豈不是無法調用線程函數了?
【haoranisme】:
試想一下,如果可以用非靜態成員函數作為線程函數,如果沒有定義一個這個類的實例,
豈不是無法調用線程函數了?
++++++++++++++++++++++++++++++++++++++++++++++++++++
不明白呀!
【LiChenYue】:
學習!關注!
【robinwjb】:
試想一下,如果可以用非靜態成員函數作為線程函數,如果沒有定義一個這個類的實例,
豈不是無法調用線程函數了?
++++++++++++++++++++++++++++++++++++++++++++++++++++
不明白呀!
------------------------------------------------------------
靜態成員(無論是函數還是變量)是存儲在全局變量區的,也就是在整個程序生命中有效的。
而非靜態成員是隨類的實例生成而生,隨著類的實例死亡而死的。
所以,如果非靜態成員函數作為線程函數的話,此時這個類的實例不存在,而程序要生成線程了,卻發現線程函數根本不存在。
【haoranisme】:
非靜態成員函數,也存儲全局變量區(堆區)吧?
【chehw】:
設某函數原型為LRESULTThreadProc(LPVOIDpv);
若為非靜態成員函數,編譯時自動展開為ThreadProc(pClass->this,pv);與線程函數調用不相符。所以必須使用全局函數或類靜態成員函數
【haoranisme】:
會不會是為了區分代碼段和數據段呢?
【robinwjb】:
非靜態成員函數,也存儲全局變量區(堆區)吧?
------------------------------------------------
如果沒有類的實例,則非靜態成員函數沒有存儲空間。
只是作為代碼存在代碼區
【wltg2001】:
成員函數都有一個隱含參數this,也就是指向這個對象實例的指針,所以不能做啟動函數
【wltg2001】:
用成員函數作線程啟動函數編譯應該都不會過,就是因為參數不匹配的原因
【haoranisme】:
感覺不象
【kouzhongling】:
設某函數原型為LRESULTThreadProc(LPVOIDpv);
若為非靜態成員函數,編譯時自動展開為ThreadProc(pClass->this,pv);與線程函數調用不相符。所以必須使用全局函數或類靜態成員函數
---------------------------------------------
同意
作為線程入口當然不應該與類對象共存亡應該具有全局性
俺認為所有方法均在于代碼段至于堆中是否存有可執行代碼我也想知道
我一直認為堆只是存放數據的地方
【haoranisme】:
謝謝各位了!
【Nowish】:
mark~
|
|
VC6中,為什么只有類中的static成員函數,才可以做為線程啟動函數(ThreadProc)?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元