詳解c++中的 static 關鍵字及作用
注:若沒有特指是 靜態成員時,預設都是普通成員;
1 類中的普通成員
類中的成員變數 和 成員函式 是分開儲存的。其中,
1)每個物件都有獨立的成員變數;成員變數可以儲存在 棧空間、堆空間、全域性資料區;
2)所有物件共享類的成員函式;成員函式 只能儲存在 程式碼段;
2 類中的靜態成員(static)
類中的靜態成員
1、用 static關鍵字 修飾;
2、可以用 類名::成員名 訪問 靜態成員;
3、靜態成員 屬於 整個類;
4、靜態成員 是所屬類的成員,其它類不能訪問;
5、靜態成員的記憶體分配 是 唯一的;
1) 靜態成員變數
特徵:1、靜態成員變數 屬於 整個類所有;
2、靜態成員變數的生命週期不依賴任何物件;(靜態成員變數的生命週期在程式的執行期)
3、所有物件共享類的靜態成員變數;
4、可以通過 類名 直接訪問公有的靜態成員變數;
5、可以通過 物件名 訪問公有的靜態成員變數;
6、靜態成員變數 需要在類外單獨分配空間;(類內宣告、類外定義並初始化)
7、靜態成員變數 在程式內部位於全域性資料區,不計入類的記憶體計算。
原因/好處:使用靜態成員變數實現多個物件之間的資料共享不會破壞隱藏的原則,保證了安全性還可以節省記憶體。
使用方法:
1、在類的內部,使用 static 修飾普通成員變數;
2、在類的外部(全域性作用域),使用 Type ClassName::VarName = value 初始化,並申請儲存空間;
注:靜態成員變數不屬於類的任何物件,所以並不是物件建立時被定義的,所以它不能由類的建構函式初始化,一般也不能在類內初始化;
/* 靜態成員變數 只能在類的內部宣告,在類的外部(全域性區)定義和初始化; */ #include <iostream> using namespace std; class Test{ public: int GetA() const{return a;} private: static int a; // 靜態成員變數 }; //int Test::a;如果這樣定義不賦予初值,則初值為零 int Test::a = 1; int main(int argc,char *argv[]) { Test T; cout << T.GetA() << endl; return 0; }
靜態成員變數 被類的所有物件共享,包括派生類物件;
#include <iostream> using namespace std; class Base{ public: static int a; // 靜態成員變數 }; // int Test::a;如果這樣定義不賦予初值,則初值為零 int Base::a; class Derived : public Base{ }; int main(int argc,char *argv[]) { Base B; Derived D; B.a++; cout << B.a << endl; // 1 D.a++; cout << D.a << endl; // 2 return 0; }
靜態成員變數可以作為普通成員函式的預設形參,而普通成員變數則不可以;
class Test{ public: static int a; //靜態成員變數 int b; void fun_1(int i = a); //正確 //void fun_2(int i = b); //報錯 };
靜態成員變數的型別 可以是所屬類的型別,而普通成員變數則不可以。普通成員變數只能宣告為 所屬類型別的 指標或引用;
class Test{ public: static Test a; //正確 Test b; //報錯 Test *pTest; //正確 Test &m_Test; //正確 static Test *pStaticObject; //正確 };
靜態成員變數在const函式中可以修改,而普通的成員變數是萬萬不能修改的;
/* const修飾的是當前this指標所指向的物件是const,但是靜態成員變數不屬於任何類的物件,它被類的所有物件修改,所以this指標不修飾靜態的成員變數,所以可以更改。 */ class Test{ public: static int a; int b; public: Test():b(0){} void test() const { a++; //b++; // err // const指的是不能修改當前呼叫該函式物件的成員變數 } }; int Test::a;
2)靜態成員函式
特徵:1、靜態成員函式 屬於 整個類所有;
2、所有物件共享類的靜態成員函式;
2、可以通過 類名 直接訪問公有的靜態成員函式;
3、可以通過 物件名 訪問公有的靜態成員函式;
4、靜態成員函式 只能 訪問靜態成員,不能訪問 非靜態成員;
5、靜態成員函式沒有this指標,也就是說靜態成員函式不能使用修飾符(也就是函式後面的const關鍵字);
原因:處理靜態成員變數;
使用方法:直接用 static 修飾 普通成員函式(類內宣告時),不需要 static 修飾(類外定義時);
總結:
案例分析:
/** * 統計某班選修課考試的平均成績 */ #include <iostream> #include <string> using namespace std; class Student { private: string name; // 姓名 string gender; // 性別 float score; // 分數 string subject; // 課程 static int total_counts; // 總人數 static float chinese_scores; // 語文分數 static int chinese_counts; // 語文課人數 static float math_scores; // 數學分數 static int math_counts; // 數學課人數 public: Student(string name,string gender,float score,string subject); ~Student(); static float aveScores(string subject); void printStudentInfo(); void printAveScores(); }; int Student::total_counts = 0; float Student::chinese_scores = 0; int Student::chinese_counts = 0; float Student::math_scores = 0; int Student::math_counts = 0; Student::Student(string name,string subject) { this->name = name; this->gender = gender; this->score = score; this->subject = subject; if(subject == "chinese" || subject == "語文") { chinese_scores += score; chinese_counts++; } else if(subject == "math" || subject == "數學") { math_scores += score; math_counts++; } else { cout << "this is no the subect:" << subject << endl; } total_counts += (chinese_counts + math_counts); } Student::~Student() { total_counts--; chinese_counts--; math_counts--; } float Student::aveScores(string subject) { float ave_score = 0; if(chinese_counts > 0 && subject == "chinese" || subject == "語文") { ave_score = (chinese_scores / chinese_counts); //cout << subject << "\t" << chinese_counts << "\t" << chinese_scores << endl; } else if(math_counts > 0 && subject == "math" || subject == "數學") { ave_score = (math_scores / math_counts); //cout << subject << "\t" <<math_counts << "\t" << math_scores << endl; } return ave_score; } void Student::printStudentInfo() { cout << name << "\t" << gender << "\t" << score << "\t" << subject << endl; } void Student::printAveScores() { cout <<subject << " average score: " << aveScores(subject) << endl; } int main(int argc,char const *argv[]) { const int SIZE = 5; Student stu[SIZE] = { Student("10001","male",92,"語文"),Student("10002",91,"數學"),Student("10003",Student("10004",93,Student("10005",}; for(int i = 0; i < SIZE; i++) { stu[i].printStudentInfo(); } stu[0].printAveScores(); stu[1].printAveScores(); cout << "語文" << " average score: " << Student::aveScores("語文") << endl; cout << "數學" << " average score: " << Student::aveScores("數學") << endl; return 0; } 靜態成員的案例分析
下面看下c語言中的static關鍵字的作用
在我們日常使用過程中,static通常有兩個作用:
1、修飾變數
靜態全域性變數:全域性變數前加static修飾,該變數就成為了靜態全域性變數。我們知道,全部變數在整個工程都可以被訪問(一個檔案中定義,其它檔案使用的時候新增extern關鍵字宣告 ),而在添加了static關鍵字之後,這個變數就只能在本檔案內被訪問了。因此,在這裡,static的作用就是限定作用域。
靜態區域性變數:局不變數添加了static修飾之後,該變數就成為了靜態區域性變數。我們知道區域性變數在離開了被定義的函式後,就會被銷燬,而當使用static修飾之後,它的作用域就一直到整個程式結束。因此,在這裡static的作用就是限定生命週期。
2、修飾函式
修飾函式則該函式成為靜態函式,函式的作用域僅限於本檔案,而不能被其它檔案呼叫。
總結
以上所述是小編給大家介紹的c++中的 static 關鍵字及作用,希望對大家有所幫助!