C++ const 與 static變量、函數(shù)、類成員的全面解析(最新推薦)
1. const 常量的初始化與賦值
基本類型 const 變量
// 必須初始化,不能先聲明后賦值 const int a = 10; // 正確:定義時(shí)初始化 const double PI = 3.14159; // 正確 // const int b; // 錯(cuò)誤:未初始化常量 // b = 20; // 錯(cuò)誤:不能給常量賦值
const 指針和引用
int x = 10, y = 20; // const 指針(指向常量的指針) const int* ptr1 = &x; // 正確:指向的內(nèi)容不可變 // *ptr1 = 30; // 錯(cuò)誤:不能通過ptr1修改x ptr1 = &y; // 正確:指針本身可以指向其他地址 // 常量指針(指針本身是常量) int* const ptr2 = &x; // 正確:指針本身不可變 *ptr2 = 30; // 正確:可以通過ptr2修改x // ptr2 = &y; // 錯(cuò)誤:ptr2是常量指針 // 指向常量的常量指針 const int* const ptr3 = &x; // 指針和指向的內(nèi)容都不可變 // const 引用 const int& ref = x; // 正確:引用不可修改其值 // ref = 40; // 錯(cuò)誤:不能通過ref修改x
類中的 const 成員變量
class MyClass {
private:
const int id; // const 成員變量
const std::string name;
public:
// 必須在初始化列表中初始化
MyClass(int idVal, const std::string& nameVal)
: id(idVal), name(nameVal) { // 初始化列表
// id = idVal; // 錯(cuò)誤!不能在構(gòu)造函數(shù)體內(nèi)賦值
}
// 委托構(gòu)造函數(shù)也要通過初始化列表
MyClass() : MyClass(0, "Unknown") {}
};const 成員變量的特殊情況
class AdvancedClass {
private:
const int size = 100; // C++11: 類內(nèi)直接初始化
static const int COUNT = 50; // 靜態(tài)常量可以在類內(nèi)初始化
public:
AdvancedClass() {} // 使用默認(rèn)值
AdvancedClass(int s) : size(s) {} // 可以覆蓋默認(rèn)值
};const 賦值規(guī)則總結(jié)
- 基本類型 const 變量:必須在定義時(shí)初始化,之后不能賦值
- const 成員變量:必須在構(gòu)造函數(shù)的初始化列表中初始化
- const 指針/引用:遵循指針和引用的 const 規(guī)則
- 編譯時(shí)常量:可以使用
constexpr獲得更好的優(yōu)化
2. static 變量的使用
靜態(tài)局部變量
void counterFunction() {
static int count = 0; // 只在第一次調(diào)用時(shí)初始化
count++;
std::cout << "Called " << count << " times" << std::endl;
}
// 使用
counterFunction(); // Called 1 times
counterFunction(); // Called 2 times
counterFunction(); // Called 3 times靜態(tài)成員變量
class Player {
private:
static int totalPlayers; // 聲明
std::string name;
int score;
public:
Player(const std::string& n) : name(n), score(0) {
totalPlayers++; // 創(chuàng)建對象時(shí)計(jì)數(shù)
}
~Player() {
totalPlayers--; // 銷毀對象時(shí)減計(jì)數(shù)
}
static int getTotalPlayers() {
return totalPlayers;
}
};
// 靜態(tài)成員變量必須在類外定義
int Player::totalPlayers = 0; // 定義和初始化
// 使用
Player p1("Alice");
Player p2("Bob");
std::cout << Player::getTotalPlayers(); // 輸出: 2靜態(tài)常量成員變量
class MathConstants {
public:
static const double PI; // 需要類外定義
static constexpr double E = 2.71828; // C++11: 可以在類內(nèi)初始化
// 整型靜態(tài)常量可以在類內(nèi)初始化(歷史原因)
static const int MAX_SIZE = 100;
};
// 類外定義(如果使用了取地址操作,必須定義)
const double MathConstants::PI = 3.14159;
const int MathConstants::MAX_SIZE; // 定義,不需要重復(fù)初始化3. static 函數(shù)的使用
靜態(tài)成員函數(shù)
class Utility {
private:
static int instanceCount;
int instanceData; // 非靜態(tài)成員
public:
Utility() { instanceCount++; }
// 靜態(tài)成員函數(shù)
static int getInstanceCount() {
return instanceCount;
// return instanceData; // 錯(cuò)誤!不能訪問非靜態(tài)成員
}
static double calculateDistance(double x1, double y1, double x2, double y2) {
// 工具函數(shù),不依賴對象狀態(tài)
return std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}
// 工廠方法模式
static Utility* createUtility() {
return new Utility();
}
};
int Utility::instanceCount = 0;
// 使用靜態(tài)函數(shù)
int main() {
std::cout << Utility::getInstanceCount(); // 直接通過類名調(diào)用
std::cout << Utility::calculateDistance(0, 0, 3, 4); // 輸出: 5
Utility u1;
std::cout << u1.getInstanceCount(); // 也可以通過對象調(diào)用(不推薦)
}文件作用域的靜態(tài)函數(shù)(C風(fēng)格)
// 在 .cpp 文件中
static void internalHelper() { // 只在當(dāng)前文件可見
std::cout << "內(nèi)部幫助函數(shù)" << std::endl;
}
// 替代方案:使用匿名命名空間(推薦)
namespace {
void anotherHelper() { // 同樣具有內(nèi)部鏈接
std::cout << "另一個(gè)幫助函數(shù)" << std::endl;
}
}4. 綜合應(yīng)用示例
單例模式(Singleton)
class DatabaseConnection {
private:
static DatabaseConnection* instance; // 靜態(tài)實(shí)例指針
const std::string connectionString; // const 成員
mutable std::mutex mtx; // mutable:可在const函數(shù)中修改
// 私有構(gòu)造函數(shù)
DatabaseConnection(const std::string& connStr)
: connectionString(connStr) {}
public:
// 刪除拷貝構(gòu)造和賦值
DatabaseConnection(const DatabaseConnection&) = delete;
DatabaseConnection& operator=(const DatabaseConnection&) = delete;
// 靜態(tài)函數(shù)獲取單例
static DatabaseConnection* getInstance() {
if (instance == nullptr) {
instance = new DatabaseConnection("localhost:3306");
}
return instance;
}
// const 成員函數(shù)
const std::string& getConnectionString() const {
return connectionString;
}
// 可修改 mutable 成員的 const 函數(shù)
void query(const std::string& sql) const {
std::lock_guard<std::mutex> lock(mtx); // 修改 mutable 成員
std::cout << "Executing: " << sql << std::endl;
}
static void cleanup() {
delete instance;
instance = nullptr;
}
};
// 靜態(tài)成員定義
DatabaseConnection* DatabaseConnection::instance = nullptr;使用示例
int main() {
// 單例使用
DatabaseConnection* db = DatabaseConnection::getInstance();
db->query("SELECT * FROM users");
// const 對象使用
const DatabaseConnection* constDb = DatabaseConnection::getInstance();
std::cout << constDb->getConnectionString() << std::endl;
constDb->query("SELECT * FROM products"); // 可以調(diào)用 const 函數(shù)
DatabaseConnection::cleanup();
return 0;
}5. 關(guān)鍵要點(diǎn)總結(jié)
const 規(guī)則
- 必須初始化:所有 const 變量必須在創(chuàng)建時(shí)初始化
- 不能賦值:初始化后不能再修改值
- 成員變量:必須在構(gòu)造函數(shù)初始化列表中初始化
- mutable 例外:mutable 成員在 const 函數(shù)中可修改
static 規(guī)則
- 靜態(tài)變量:類級(jí)別共享,必須在類外定義
- 靜態(tài)函數(shù):無 this 指針,只能訪問靜態(tài)成員
- 生命周期:整個(gè)程序運(yùn)行期間存在
- 訪問方式:推薦使用
ClassName::member方式訪問
最佳實(shí)踐
- 將不修改對象狀態(tài)的成員函數(shù)聲明為
const - 使用
static實(shí)現(xiàn)工具函數(shù)和單例模式 - 優(yōu)先使用匿名命名空間替代文件作用域的 static 函數(shù)
- 合理使用
mutable處理 const 函數(shù)中的特殊情況
到此這篇關(guān)于C++ const 與 static變量、函數(shù)、類成員的全面解析(最新推薦)的文章就介紹到這了,更多相關(guān)C++ const 與 static 類成員內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
舉例分析private的作用(c/c++學(xué)習(xí))
我知道我們可以用 public 中的值,把private中的數(shù)據(jù)給提出來,但是還是搞不懂private該怎么用,或者說在一個(gè)具體程序中,private有什么用2020-08-08
C++實(shí)現(xiàn)LeetCode( 69.求平方根)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode( 69.求平方根),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++利用對象池優(yōu)化內(nèi)存管理解決MISRA報(bào)警的代碼詳解
本篇詳細(xì)講解如何用對象池技術(shù)優(yōu)化C++項(xiàng)目中的內(nèi)存管理,徹底消除new/delete帶來的MISRA報(bào)警,兼顧高性能與安全規(guī)范,需要的朋友可以參考下2025-07-07
C語言的字符串函數(shù),內(nèi)存函數(shù)筆記詳解
這篇文章主要給大家介紹了關(guān)于C語言字符串/內(nèi)存的相關(guān)函數(shù),文中通過示例代碼總結(jié)的非常詳細(xì),對大家學(xué)習(xí)或者使用C語言具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2021-09-09
c++ std::sort使用自定義的比較函數(shù)排序方式
文章介紹了使用std::sort對容器內(nèi)元素進(jìn)行排序的基本方法,包括自定義排序函數(shù)和在類中調(diào)用自定義成員函數(shù)進(jìn)行排序的方法,文章還指出了在傳遞成員函數(shù)指針時(shí)可能會(huì)遇到的錯(cuò)誤,并提供了使用Lambda表達(dá)式的解決辦法2025-02-02
OpenCV基于稠密光流實(shí)現(xiàn)視頻跟蹤詳解
這篇文章主要為大家詳細(xì)介紹了OpenCV如何基于稠密光流實(shí)現(xiàn)視頻跟蹤功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-02-02
C++中std::ifstream::readsome和std::ifstream::read的區(qū)別解析
?std::ifstream::readsome和std::ifstream::read?的主要區(qū)別在于它們處理輸入流的方式和可能返回的結(jié)果,下面給大家介紹C++中std::ifstream::readsome和std::ifstream::read的區(qū)別解析,感興趣的朋友跟隨小編一起看看吧2024-08-08

