需要更好的閱讀的體驗請移步 👉 小牛肉的個人部落格 👈
文章目錄
-
- 一、辨別符的作用域與可見性
- 二、對象的生存期
-
- 1. 靜态生存期
- 2. 動态生存期
- 三、變量的生存期與可見性綜合示例
- 四、類的靜态成員 static
-
- 1. 靜态成員變量
- 2. 靜态成員函數
- 五、類的友元 friend
-
- 1. 友元函數
- 2. 友元類
- 六、共享資料的保護 (const)
-
- 1. 常對象
- 2. 常成員
-
- 常成員函數
- 常資料成員
- 3. 常引用
一、辨別符的作用域與可見性
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLycGVPpXTU1EeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0cDN0MjNxAjM4IzMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
二、對象的生存期
1. 靜态生存期
- 這種生存期與程式的運作期相同。
- 在檔案作用域中聲明的對象具有這種生存期。
- 在函數内部聲明靜态生存期對象,要冠以關鍵字
。static
2. 動态生存期
- 塊作用域中聲明的,沒有用static修飾的對象是動态生存期的對象(習慣稱局部生存期對象)。
- 開始于程式執行到聲明點時,結束于命名該辨別符的作用域結束處。
三、變量的生存期與可見性綜合示例
思考:在函數内部定義的普通局部變量和靜态局部變量在功能上有何不同?計算機底層對這兩類變量做了
怎樣的不同處理?
- 局部作用域中的靜态變量: 不會随着每次函數的調用而産生一個副本,也不會随着函數的傳回而失效,定義時未指定初值的會被以0初始化
- 局部作用域中的全局變量:誕生于聲明點,結束于聲明所在塊執行完畢之時,并且不指定初值意味着初值不确定
四、類的靜态成員 static
靜态成員函數/變量本質上是全局函數/變量,哪怕一個對象都不存在,類的靜态成員都還是存在的。
那為什麼還要設定靜态成員而不直接設定成全局函數/變量呢?
- 是為了将和某些類緊密相關的全局變量和函數寫到類裡面,使其看上去像一個整體,便于維護和了解。
注:私有的靜态成員在類外依然不能通路
1. 靜态成員變量
class A{
int n;
static int s;
}
int A :: s = 2; //類外初始化
- 所有對象共享,維護同一個副本,即對象 n1 修改其值,對象 n2 中的值也會改變。
- sizeof(A) = 4;sizeof不會計算靜态成員變量
- 靜态成員變量必須在類外進行一次說明或初始化,否則編譯能通過但連結不能通過
2. 靜态成員函數
普通成員函數必須具體作用于某個對象(即通過 對象名. 通路),
而靜态成員函數并不具體作用于某個對象,不需要通過對象就能通路。
靜态成員函數的通路方式:
- 類名::成員名(無須對象,直接通過類名通路)
- 對象名.成員名
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
1. 友元函數
2. 友元類
特别注意:友元關系不能繼承;不能傳遞;單向 !
六、共享資料的保護 (const)
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 修飾的對象成員
常成員函數
例:
常成員函數執行期間不應該修改其所作用的對象,即:
- 在常量成員函數中不能修改成員變量的值(靜态成員變量除外)
- 也不能調用同類的非常量成員函數(靜态成員函數除外)
例:
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 在類外進行說明和初始化
例:
3. 常引用
當需要對象作為參數時,生成該參數需要調用複制構造函數,效率比較低,用指針做參數,代碼會比較不好看,是以用對象的引用做參數
void func(A &a)
使用對象引用作參數有一定的風險性,若函數中修改了形參a,則實參也跟着變,有時候這可能不是開發者想要的。若不想要對象發生改變,則使用const限定:
void func(const A &a)
例: