c++,static 静态成员变量 / 静态成员函数
生活随笔
收集整理的這篇文章主要介紹了
c++,static 静态成员变量 / 静态成员函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
靜態成員變量:
//靜態成員變量(static) // //1.如果想在同類的多個對象之間實現數據共享 ,可以用靜態 //成員變量,即用static修飾的成員變量,例 static int a; //靜態成員變量在項目剛運行的時候就分配內存,項目運 //行結束以后才銷毀。 // //2.靜態成員變量被它所屬類創建的所有對象共享。 // //3.靜態成員變量必須在類體外初始化。 //格式為:類型 類名∷靜態成員變量 = 初值 //例: int Stu :: a = 20; // //4.訪問靜態成員變量有兩種方式: // //(1)與普通過成員變量一樣,可以通過對象、對象指針或 //對象引用來訪問。 // //(2)用靜態成員變量所屬類的類名來訪問, //即“類名::靜態成員變量名”。?
靜態成員函數:
//1、訪問靜態成員函數的方式有兩種 // (1)與普通成員函數被訪問方式一樣,可以用對象、指針和引用來訪問 // (2)另外,使用 所屬類名::靜態成員函數名引用。//2、靜態成員函數中沒有"this.", 而是用"類名::"替代了"this."; //(1) static成員函數中不能訪問普通的成員。 //(2)static成員函數可通過 類名::成員 訪問靜態成員。 #include <iostream> using namespace std ; #include <string> //--------------------------------------------------------------- class Demo{//模擬一個人 public:int m_age ;char m_name[10] ;static int m_country;Demo(char* s , int age,int country);//構造函數static void show(void); //介紹自己 void presence(void); //介紹自己 };Demo::Demo(char* s ,int age ,int country=111) {strcpy(this->m_name , s);this->m_age = age ;this->m_country = country; }//--------------------------------------------------------------- int Demo::m_country = 111;//chinavoid Demo::show() {//cout<<"name:"<<m_name<<endl;//error C2597: 對非靜態成員“Demo::m_name”的非法引用//cout<<"age:"<<m_age<<endl;//error C2597: 對非靜態成員“Demo::m_age”的非法引用//cout<<"country:"<<this->m_country<<endl;//error C2355: “this”: 只能在非靜態成員函數的內部引用//cout<<"country:"<<m_country<<endl;//ok 可以訪問靜態成員cout<<"country:"<<Demo::m_country<<endl;//ok 可以訪問類名::靜態成員 } void Demo::presence() {cout<<"name:"<<m_name<<endl;cout<<"age:"<<m_age<<endl;cout<<"country:"<<m_country<<endl;//ok//cout<<"country:"<<this->m_country<<endl;//ok//cout<<"country:"<<Demo::m_country<<endl;//ok } //----------------------------------------------------------------int main() {Demo demo1("caicai" , 18 , 112);demo1.show();Demo demo2("benben",16);demo2.show();demo2.presence();//Demo::m_country是該類對象公有的【地址空間、值】,如本例中demo1、demo2共用。 //外部函數main可以直接訪問靜態成員Demo::m_country。cout<<"靜態成員變量 Demo::m_country="<<Demo::m_country<<endl;cout<<"靜態成員變量 demo1.m_country="<<demo1.m_country<<endl;cout<<"靜態成員變量 demo2.m_country="<<demo2.m_country<<endl;while(1); } /* country:112 //demo1.show(); country:111 //demo2.show();name:benben //demo2.presence(); age:16 country:111 */?
C++中的類成員聲明static:[1]
在類中聲明static變量或者函數時,初始化時使用作用域運算符來標明它所屬類,因此,靜態數據成員是類的成員,而不是對象的成員,這樣就出現以下作用:(1)類的靜態成員函數是屬于整個類而非類的對象,所以它沒有this指針,這就導致 了它僅能訪問類的靜態數據和靜態成員函數。 (2)不能將靜態成員函數定義為虛函數。 (3)由于靜態成員聲明于類中,操作于其外,所以對其取地址操作,就多少有些特殊 ,變量地址是指向其數據類型的指針 ,函數地址類型是一個“nonmember函數指針”。(4)由于靜態成員函數沒有this指針,所以就差不多等同于nonmember函數,結果就 產生了一個意想不到的好處:成為一個callback函數,使得我們得以將C++和C-based X Window系統結合,同時也成功的應用于線程函數身上。[2] [3]#include <iostream>// [2]
using namespace std;#include "windows.h" #include <process.h> class ExampleTask { public: static void taskThread(LPVOID param);friend void funcex(LPVOID param);void func(){cout<<"in func,"<<endl;}}; void funcex(LPVOID param) {cout<<"\nfuncex,"<<endl;ExampleTask *pOeg = (ExampleTask*) param ;pOeg->func(); }void ExampleTask::taskThread(LPVOID param) {ExampleTask *pOeg = (ExampleTask*) param ;pOeg->func(); } int main(int argc, char* argv[]) { ExampleTask realTimeTask; //使用傳入指針的方法,用類的靜態成員函數調用類的其它函數。//在c++的語法中,靜態成員函數不能操作非靜態成員。realTimeTask.taskThread(&realTimeTask);//測試打印taskThread結果 : in func, //那么,這樣定義的意義是什么呢?下面就是一種應用方式:使得類的成員函數可以作為線程函數。//一般來說,C++的類成員函數不能作為線程函數。這是因為在類中定義的成員函數,編譯器會給其加上this指針。//將類的靜態成員函數用作線程函數_beginthread(ExampleTask::taskThread,0,NULL); //在線程中使用taskThread結果 :in func ,//另外,欲要在線程中使用類的方法,也可以使用友元函數。//將友元函數用作線程函數,這里的話題與static方法無關了。_beginthread(funcex,0,NULL); // 在友元函數funcex中調用taskThread,再在線程中使用funcex結果 : funcex , in func,while(1);return 0; } #include <iostream> //[3] using namespace std;#include "windows.h" #include <process.h> class CTest { public:CTest();~CTest();static DWORD WINAPI ThreadCallback(PVOID pParam); //這個是系統要的東東,沒有對象也能直接訪問STATIC成員函數 DWORD MyProc(); private:HANDLE m_hThread; };CTest::CTest():m_hThread(NULL) {m_hThread = CreateThread(NULL, 0, ThreadCallback, (LPVOID)this, 0, NULL); //注意把THIS指針當做PARAM傳進去,沒這個我們就不用玩了//ASSERT(m_hThread); }CTest::~CTest() {if(m_hThread){TerminateThread(m_hThread, 1);m_hThread = NULL;} }DWORD WINAPI CTest::ThreadCallback(PVOID pParam)//Callback函數可以聲明成ThreadCallback(CTest* pCTest),而作為線程的函數參數必須聲明成(PVOID pParam)。 {return ((CTest*)pParam)->MyProc(); //把pParam還原成指向當前對象的指針,然后曲線救國一下 }DWORD CTest::MyProc() //這個就是對象里的東西了,在里面可以為所欲為 {//do whatever you want//even visit the private membercout<<"MyProc"<<endl;return 0 ; }int main() {CTest oTst;
while(1);return 0 ; } (5)static并沒有增加程序的時空開銷,相反她還縮短了子類對父類靜態成員的訪問 時間,節省了子類的內存空間。 (6)靜態數據成員在<定義或說明>時前面加關鍵字static。 (7)靜態數據成員是靜態存儲的,所以必須對它進行初始化。 (程序員手動初始化,否則編譯時一般不會報錯,但是在Link時會報錯誤) (8)靜態成員初始化與一般數據成員初始化不同:初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆; 初始化時不加該成員的訪問權限控制符private,public等; 初始化時使用作用域運算符來標明它所屬類;所以我們得出靜態數據成員初始化的格式: <數據類型><類名>::<靜態數據成員名>=<值>(9)為了防止父類的影響,可以在子類定義一個與父類相同的靜態變量,以屏蔽父類的影響。這里有一點需要注意:我們說靜態成員為父類和子類共享,但我們有重復定義了靜態成員,這會不會引起錯誤呢?不會,我們的編譯器采用了一種絕妙的手法:name-mangling 用以生成唯一的標志。
?
參考:
1 . C/C++中static關鍵字作用總結?
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/19/2598815.html
2. ?類成員函數作為線程函數
http://blog.163.com/lyz_sea/blog/static/115586707201101025443711/
3. ?靜態成員函數運用在CALLBACK函數和線程函數中?
http://www.cnblogs.com/kanego/articles/2268723.html
轉載于:https://www.cnblogs.com/mylinux/p/4092415.html
總結
以上是生活随笔為你收集整理的c++,static 静态成员变量 / 静态成员函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Xtrabackup 安装使用
- 下一篇: 一些C和C++的常见问题集锦 ----不