C++ 的存儲類別
你好,有抱負的程式設計師們!今天,我們將踏上一段令人興奮的旅程,探索C++存儲類別的世界。別擔心如果你是編程新手;我將成為你友好的導遊,逐步解釋一切。讓我們一起來看看吧!
什麼是存儲類別?
在我們深入具體內容之前,讓我們先了解存儲類別是什麼。在C++中,存儲類別定義了變量和函數在程序中的作用域(可見性)和生命周期。它們告訴編譯器如何存儲變量,它是否從其他文件中可訪問,以及它在記憶體中應該存在多長時間。
現在,讓我們詳細探索每種存儲類別。
auto 存儲類別
在C++中,auto
關鍵字隨著時間的推移改變了它的含義。在現代C++(C++11及之後版本)中,它用於類型推斷。然而,在較舊的版本中,它是一個存儲類別指定符。
舊用法(C++11之前):
int main() {
auto int x = 5; // 等價於:int x = 5;
return 0;
}
在這個舊用法中,auto
明確聲明了一個具有自動存儲周期的變量。然而,這是本地變量的默認設定,所以很少使用。
現代用法(C++11及之後):
int main() {
auto x = 5; // x被推斷為int
auto y = 3.14; // y被推斷為double
auto z = "Hello"; // z被推斷為const char*
return 0;
}
在現代C++中,auto
讓編譯器根據初始化器推斷變量的類型。當類型可能變化或在將來變化時,它特別有用。
register 存儲類別
register
關鍵字是給編譯器的暗示,表示這個變量將被大量使用,並應該保持在CPU寄存器中以供快速訪問。
#include <iostream>
int main() {
register int counter = 0;
for(int i = 0; i < 1000000; i++) {
counter++;
}
std::cout << "計數器: " << counter << std::endl;
return 0;
}
在這個例子中,我們建議編譯器將counter
保持在寄存器中。然而,現代編譯器通常足夠聰明,能夠自行進行這些優化,所以register
在實踐中很少使用。
static 存儲類別
static
關鍵字根據其使用位置有不同的含義:
1. 靜態本地變量
#include <iostream>
void countCalls() {
static int calls = 0;
calls++;
std::cout << "這個函數已被調用 " << calls << " 次。" << std::endl;
}
int main() {
for(int i = 0; i < 5; i++) {
countCalls();
}
return 0;
}
在這個例子中,calls
只初始化一次,並在函數調用之間保持其值。輸出將會是:
這個函數已被調用 1 次。
這個函數已被調用 2 次。
這個函數已被調用 3 次。
這個函數已被調用 4 次。
這個函數已被調用 5 次。
2. 靜態類成員
class MyClass {
public:
static int objectCount;
MyClass() {
objectCount++;
}
};
int MyClass::objectCount = 0;
int main() {
MyClass obj1;
MyClass obj2;
MyClass obj3;
std::cout << "創建的物件數量: " << MyClass::objectCount << std::endl;
return 0;
}
在這裡,objectCount
在所有MyClass
的實例之間共享。輸出將會是:
創建的物件數量: 3
extern 存儲類別
extern
關鍵字用於在另一個文件中聲明全局變量或函數。
文件:globals.cpp
int globalVar = 10;
文件:main.cpp
#include <iostream>
extern int globalVar; // 聲明 globalVar
int main() {
std::cout << "全局變量值: " << globalVar << std::endl;
return 0;
}
在這個例子中,globalVar
在globals.cpp
中定義,並在main.cpp
中作為extern
聲明。這樣main.cpp
就可以使用在另一個文件中定義的變量。
mutable 存儲類別
mutable
關鍵字允許const對象的成員被修改。
class Person {
public:
Person(int age) : age(age), cacheValid(false) {}
int getAge() const {
if (!cacheValid) {
cachedAge = heavyComputation();
cacheValid = true;
}
return cachedAge;
}
private:
int age;
mutable int cachedAge;
mutable bool cacheValid;
int heavyComputation() const {
// 模擬一個耗時計算
return age;
}
};
int main() {
const Person p(30);
std::cout << p.getAge() << std::endl; // 這是允許的
return 0;
}
在這個例子中,即使p
是const,我們也可以修改cachedAge
和cacheValid
,因為它們被標記為mutable
。
總結
讓我們總結一下我們學到的存儲類別,並提供一個方便的表格:
存儲類別 | 用途 |
---|---|
auto | 類型推斷(現代C++) |
register | 快速訪問的暗示(很少使用) |
static | 在函數調用之間保持值或類實例間共享 |
extern | 在其他文件中聲明變量或函數 |
mutable | 在const對象中允許修改 |
記住,理解存儲類別對於有效地管理記憶體和控制變量的作用域至關重要。隨著你繼續在C++的旅程上前行,你會發現這些概念變得習以為常。祝你編程愉快!
Credits: Image by storyset