標籤:int 參數傳遞 友元函數 ted 處理 初始化 get name col
標識符的範圍與可見度
- 函數原型範圍
- 局部範圍(塊範圍)
- 類範圍
- 檔案範圍
- 命名空間範圍(詳見第10章)
函數原形範圍
- 函數原型中的參數,其範圍始於"(",結束於")"。
- 函數原形範圍舉例:double area(double radius);
局部範圍
- 函數的形參、在塊中聲明的標識符;
- 其範圍自聲明處起,限於塊中。
- 局部範圍舉例
void fun(int a) {
int b = a;
cin >> b;
if (b > 0) {
int c;
......
}
}
類範圍
- 類的成員具有類範圍,其範圍包括類體和非內聯成員函數的函數體。
- 如果在類範圍以外訪問類的成員,要通過類名(訪問靜態成員),或者該類的對象名、對象引用、對象指標(訪問非靜態成員)。
檔案範圍
- 不在前述各個範圍中出現的聲明,就具有檔案範圍,這樣聲明的標識符其範圍開始於聲明點,結束於檔案尾。
可見度
- 可見度是從對標識符的引用的角度來談的概念
- 可見度表示從內層範圍向外層範圍“看”時能看見什麼。
- 如果標識在某處可見,就可以在該處引用此標識符。
- 如果某個標識符在外層中聲明,且在內層中沒有同一標識符的聲明,則該標識符在內層可見。
- 對於兩個嵌套的範圍,如果在內層範圍內聲明了與外層範圍中同名的標識符,則外層範圍的標識符在內層不可見。
對象的生存期
靜態生存期
- 在檔案範圍中聲明的對象具有這種生存期。
- 在函數內部聲明靜態生存期對象,要冠以關鍵字static 。
動態生存期
- 塊範圍中聲明的,沒有用static修飾的對象是動態生存期的對象(習慣稱局部生存期對象)。
- 開始於程式執行到聲明點時,結束於命名該標識符的範圍結束處。
類的待用資料成員
- 用關鍵字static聲明
- 為該類的所有對象共用,待用資料成員具有靜態生存期。
- 必須在類外定義和初始化,用(::)來指明所屬的類
案例:
#include <iostream>using namespace std;class Point { //Point類定義public: //外部介面 Point(int x = 0, int y = 0) : x(x), y(y) { //建構函式 //在建構函式中對count累加,所有對象共同維護同一個count count++; } Point(Point &p) { //複製建構函式 x = p.x; y = p.y; count++; } ~Point() { count--; } int getX() { return x; } int getY() { return y; } void showCount() { //輸出待用資料成員 cout << " Object count = " << count << endl; }private: //私人資料成員 int x, y; static int count; //待用資料成員聲明,用於記錄點的個數};int Point::count = 0;//待用資料成員定義和初始化,使用類名限定int main() { //主函數 Point a(4, 5); //定義對象a,其建構函式回使count增1 cout << "Point A: " << a.getX() << ", " << a.getY(); a.showCount(); //輸出對象個數 Point b(a); //定義對象b,其建構函式回使count增1 cout << "Point B: " << b.getX() << ", " << b.getY(); b.showCount(); //輸出對象個數 return 0;}
上面案例中,我們需要記錄下point類的對象的數目,我們不可能將這個變數存放於類的私人成員中,因為這樣只能通過對象取訪問,並且每聲明一個類的對象,這個數目就要增加1。因此,我們可以將其定義為類的靜態成員變數,這個變數是為所有的類對象共有的。但是,這樣也會存在一個問題:當沒有定義類的對象時,我們能不能知道類對象的個數呢?如果要通過類的對象來訪問這個變數的話,那麼需要先聲明一個對象,但是類的對象還沒有被聲明,如何解決這個問題呢?這就需要用到類的靜態函數成員了。
類的靜態函數成員
- 類外代碼可以使用類名和範圍操作符來調用靜態成員函數。
- 靜態成員函數主要用於處理該類的待用資料成員(為什嗎?),可以直接調用靜態成員函數。
- 如果訪問非靜態成員,要通過對象來訪問。
將上面的程式稍作修改,如下:
#include <iostream>using namespace std;class Point {public: Point(int x = 0, int y = 0) : x(x), y(y) { count++; }//建構函式 Point(Point &p) { //複製建構函式 x = p.x; y = p.y; count++; } ~Point() { count--; } int getX() { return x; } int getY() { return y; } static void showCount() { cout << " Object count = " << count << endl; }private: int x, y; static int count; //待用資料成員聲明,用於記錄點的個數};int Point::count = 0;//待用資料成員定義和初始化,使用類名限定int main() { Point a(4, 5); //定義對象a,其建構函式回使count增1 cout << "Point A: " << a.getX() << ", " << a.getY(); Point::showCount(); //輸出對象個數 Point b(a); //定義對象b,其建構函式回使count增1 cout << "Point B: " << b.getX() << ", " << b.getY(); Point::showCount(); //輸出對象個數 return 0;}
我們在函數中增加了一個靜態成員函數:showcount(),那麼在訪問類的靜態成員變數時就可以不通過對象來訪問,而是通過這個靜態成員函數來訪問,即使沒有聲明類的對象。但是靜態成員函數不能直接存取對象的資料成員,而是要將對象傳遞給靜態函數才可以訪問。
類的友元
- 友元是C++提供的一種破壞資料封裝和資料隱藏的機制。
- 通過將一個模組聲明為另一個模組的友元,一個模組能夠引用到另一個模組中本是被隱藏的資訊。
- 可以使用友元函數和友元類。
- 為了確保資料的完整性,及資料封裝與隱藏的原則,建議盡量不使用或少使用友元。
友元函數
- 友元函數是在類聲明中由關鍵字friend修飾說明的非成員函數,在它的函數體中能夠通過對象名訪問 private 和protected成員
- 作用:增加靈活性,使程式員可以在封裝和快速性方面做合理選擇。
- 訪問對象中的成員必須通過對象名,也就是必須將類的對象作為參數傳遞給函數,一般我們選擇引用傳遞,因為這樣程式的開銷會更小,但是引用時資料是雙向傳遞的,因此可以在傳參數時設定為常引用,這樣就不會允許函數對傳遞進來的參數做修改了,保證了資料的安全性。
友元類
- 若一個類為另一個類的友元,則此類的所有成員都能訪問對方類的私人成員。
- 聲明文法:將友元類名在另一個類中使用friend修飾說明。
- 類的友元關係是單向的:如果聲明B類是A類的友元,B類的成員函數就可以訪問A類的私人和保護資料,但A類的成員函數卻不能訪問B類的私人、保護資料。
c++基礎(六)