天天看點

【C++複習總結回顧】—— 【四】資料的共享與保護

需要更好的閱讀的體驗請移步 👉 小牛肉的個人部落格 👈

文章目錄

    • 一、辨別符的作用域與可見性
    • 二、對象的生存期
      • 1. 靜态生存期
      • 2. 動态生存期
    • 三、變量的生存期與可見性綜合示例
    • 四、類的靜态成員 static
      • 1. 靜态成員變量
      • 2. 靜态成員函數
    • 五、類的友元 friend
      • 1. 友元函數
      • 2. 友元類
    • 六、共享資料的保護 (const)
      • 1. 常對象
      • 2. 常成員
        • 常成員函數
        • 常資料成員
      • 3. 常引用

一、辨別符的作用域與可見性

【C++複習總結回顧】—— 【四】資料的共享與保護

二、對象的生存期

1. 靜态生存期

  • 這種生存期與程式的運作期相同。
  • 在檔案作用域中聲明的對象具有這種生存期。
  • 在函數内部聲明靜态生存期對象,要冠以關鍵字

    static

2. 動态生存期

  • 塊作用域中聲明的,沒有用static修飾的對象是動态生存期的對象(習慣稱局部生存期對象)。
  • 開始于程式執行到聲明點時,結束于命名該辨別符的作用域結束處。

三、變量的生存期與可見性綜合示例

【C++複習總結回顧】—— 【四】資料的共享與保護
【C++複習總結回顧】—— 【四】資料的共享與保護

思考:在函數内部定義的普通局部變量和靜态局部變量在功能上有何不同?計算機底層對這兩類變量做了

怎樣的不同處理?

  • 局部作用域中的靜态變量: 不會随着每次函數的調用而産生一個副本,也不會随着函數的傳回而失效,定義時未指定初值的會被以0初始化
  • 局部作用域中的全局變量:誕生于聲明點,結束于聲明所在塊執行完畢之時,并且不指定初值意味着初值不确定

四、類的靜态成員 static

靜态成員函數/變量本質上是全局函數/變量,哪怕一個對象都不存在,類的靜态成員都還是存在的。

那為什麼還要設定靜态成員而不直接設定成全局函數/變量呢?

  • 是為了将和某些類緊密相關的全局變量和函數寫到類裡面,使其看上去像一個整體,便于維護和了解。

注:私有的靜态成員在類外依然不能通路

1. 靜态成員變量

【C++複習總結回顧】—— 【四】資料的共享與保護
class A{
    int n;
    static int s;
}
int A :: s = 2;  //類外初始化
           
  • 所有對象共享,維護同一個副本,即對象 n1 修改其值,對象 n2 中的值也會改變。
  • sizeof(A) = 4;sizeof不會計算靜态成員變量
  • 靜态成員變量必須在類外進行一次說明或初始化,否則編譯能通過但連結不能通過

2. 靜态成員函數

【C++複習總結回顧】—— 【四】資料的共享與保護

普通成員函數必須具體作用于某個對象(即通過 對象名. 通路),

而靜态成員函數并不具體作用于某個對象,不需要通過對象就能通路。

靜态成員函數的通路方式:

  • 類名::成員名(無須對象,直接通過類名通路)
  • 對象名.成員名
A a; 
a.s( );
           

但并不意味着隻作用于a上面

  • 指針->成員名
A *p; 
p->s( );
           

但并不意味着隻作用于a上面

  • 引用.成員名
A &q = a; 
q.s( );
           

但并不意味着隻作用于a上面

注:靜态成員函數要通路非靜态成員變量必須通過對象名.

class A
{
    int x;
public:
    static void func(A a)
    {
        cout << x; //ERROR!!!
        cout << a.x;
    }
}
           

五、類的友元 friend

【C++複習總結回顧】—— 【四】資料的共享與保護

1. 友元函數

【C++複習總結回顧】—— 【四】資料的共享與保護

2. 友元類

【C++複習總結回顧】—— 【四】資料的共享與保護

特别注意:友元關系不能繼承;不能傳遞;單向 !

六、共享資料的保護 (const)

【C++複習總結回顧】—— 【四】資料的共享與保護
Java 中沒有

const

關鍵字,與之替代的是

final

1. 常對象

用 const 修飾的對象

  • 常量對象的值不可被修改
  • 常量對象不能執行非常量成員函數,因為非常量成員函數有可能對成員變量進行修改;
  • 常量對象可以執行常量成員函數

例:

class A{
	public:
		A(int i, int j){
			x = i;
			y = j;
		}
	private:
		int x, y;
};

A const a(3,4); //常對象a,不能被更新
           

2. 常成員

用 const 修飾的對象成員

常成員函數

【C++複習總結回顧】—— 【四】資料的共享與保護

例:

【C++複習總結回顧】—— 【四】資料的共享與保護

常成員函數執行期間不應該修改其所作用的對象,即:

  • 在常量成員函數中不能修改成員變量的值(靜态成員變量除外)
  • 也不能調用同類的非常量成員函數(靜态成員函數除外)

例:

class A{
    public:
        int value;
        void setValue() const;
        void func();
}
void A :: setValue(){
    value = 0; //wrong 常量成員函數中不能修改成員變量的值
    func(); //wrong 常量成員函數中不能調用同類的非常量成員函數
} 
const A a;
a.value = 100; //wrong 常量對象的值不可被修改
a.func(); //wrong 常量對象不能執行非常量成員函數
a.setValue(); //right 常量對象可以執行常量成員函數
           

常資料成員

使用 const 說明的資料成員

  • 常資料成員 const 隻能通過構造函數的初始化清單來獲得初值
  • 靜态常資料成員 static const 在類外進行說明和初始化

例:

【C++複習總結回顧】—— 【四】資料的共享與保護

3. 常引用

當需要對象作為參數時,生成該參數需要調用複制構造函數,效率比較低,用指針做參數,代碼會比較不好看,是以用對象的引用做參數

void func(A &a)

使用對象引用作參數有一定的風險性,若函數中修改了形參a,則實參也跟着變,有時候這可能不是開發者想要的。若不想要對象發生改變,則使用const限定:

void func(const A &a)

【C++複習總結回顧】—— 【四】資料的共享與保護

例:

【C++複習總結回顧】—— 【四】資料的共享與保護
c++

繼續閱讀