奇奇怪怪的特性
1、std::call_once
std::call_once 是 C++11 引入的線程安全的一次性初始化機制,用於確保某個函數在多線程環境中只被調用一次。
使用示例:
static std::once_flag flag;
std::call_once(flag, []() {
std::thread([]() {
camera.start();
});
});
2、explicit關鍵字
explicit 是一個 C++ 關鍵字,用於修飾構造函數和C++11起支持的類型轉換運算符,它的主要作用是禁止編譯器的隱式類型轉換。Widget w1(10); // 正確:顯式構造,Widget w2 = 20; // 錯誤:隱式轉換!
3、成員初始化列表
成員初始化列表是 C++ 構造函數的一部分,用於在對象構造時初始化成員變量。
基本語法:
ClassName::ClassName(parameters) :
member1(value1),
member2(value2),
...
{
// 構造函數體
}
使用初始化成員列表,成員在進入函數體之前就已經初始化完成了。
必須使用初始化成員列表的情況:常量成員,引用成員,沒有默認構造函數的類成員,繼承-基類初始化。
初始化的順序是以類內的申明順序來的。
另外:
委託構造函數:
class Delegating {
int x, y, z;
public:
// 主構造函數
Delegating(int a, int b, int c) : x(a), y(b), z(c) {}
// 委託構造函數
Delegating() : Delegating(0, 0, 0) {} // 委託給主構造函數
Delegating(int a) : Delegating(a, 0, 0) {} // 委託給主構造函數
}; 使用函數進行初始化:
class FunctionInit {
int computed_value;
std::string processed_name;
static int computeValue() { return 42; }
static std::string processName(const std::string& n) {
return "prefix_" + n;
} public:
FunctionInit(const std::string& name) :
computed_value(computeValue()),
processed_name(processName(name))
{
}
};
4、單例模式
一種常用的設計模式,確保一個類只有一個實例,並提供全局訪問點。這種模式常用於需要全局共享的資源或管理類。
單例模式的主要特點:保證類只有一個實例,避免了不必要的資源消耗或重複操作;通過提供一個公共的靜態方法,讓全局能夠訪問到唯一的實例;實例化對象的過程通常是延遲的,只有在真正需要時才會創建。
單例模式:
getInstance()
class Singleton {
private:
static Singleton* instance;
Singleton() {} public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
}; Singleton* Singleton::instance = nullptr;
餓漢式(在程序啓動時就創建實例,不管實例是否被使用。它的優勢是 簡單,且創建實例是線程安全的,因為類的靜態成員在程序啓動時就被初始化):
class Singleton {
private:
static Singleton instance; // 在靜態成員聲明時就創建實例
Singleton() {}
public:
static Singleton& getInstance() {
return instance;
}
}; Singleton Singleton::instance;
缺點是,如果實例創建過程比較重,或者應用程序啓動時並不需要單例,餓漢式會提前消耗資源。
靜態內部類單例:
C++11 及更高版本的靜態局部變量特性來實現單例模式。這種方式既能夠懶加載,又能保證線程安全。因為靜態局部變量只會在第一次調用時初始化,而 C++ 標準保證了靜態局部變量的初始化是線程安全的。
class Singleton {
private:
Singleton() {} public:
static Singleton& getInstance() {
static Singleton instance; // C++11 保證線程安全的靜態局部變量
return instance;
}
};
註冊單例,枚舉單例。
5、四種強制轉換類型
double d = 3.14;
int a = static_cast<int>(d); // OK
Base* b = static_cast<Base*>(derivedPtr); // 向上轉型 OK
2、dynamic_cast:用於多態類的安全向下轉型。必須滿足兩個條件:基類必須有虛函數;必須啓用運行時檢查(RTTI)。
Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b);
2、const_cast:修改const/volatile的唯一方法。
const int a = 10;
int* p = const_cast<int*>(&a); // 去掉 const
4、reinterpret_cast:幾乎所有危險轉換:任意指針 ↔ 任意指針;指針 ↔ 整數(uintptr_t);不相關類型之間轉換。
使用場景:底層硬件編程;網絡協議解析;Bit-level hack;高性能場景中避免複製