標準對默認參數值限制模糊,導致編譯器差異:多允許在函數聲明、函數指針/引用、成員函數指針、typedef中包含默認值——但可移植代碼應僅在函數聲明中提供默認值。
#include
#include
class Blanks {
public:
Blanks() {}
// 額外參數chInit:分配並初始化內存
void* operator new(size_t stAllocateBlock, char chInit);
};
void* Blanks::operator new(size_t stAllocateBlock, char chInit) {
void* pvTemp = malloc(stAllocateBlock);
if (pvTemp != 0)
memset(pvTemp, chInit, stAllocateBlock);
return pvTemp;
}
int main() {
Blanks* a5 = new (0xa5) Blanks; // 創建對象,內存初始化為0xA5
return a5 != 0;
}
釋放時只能得到void*指針,可能已經類型轉換,無法知悉原始類型。實際實現:分配塊頭部隱藏大小指示器,delete讀取指示器確定釋放大小。
void f() {
X* p1 = new X[10];
// ...
delete[] p1; // 必須用[],編譯器負責記錄元素個數
}
Bjarne認為delete[10] p1易出錯,將記數任務交給實現。
delete而非delete[])std::unique_ptr(C++11)支持數組、無所有權轉移陷阱、支持自定義刪除器
// 主模板
template
struct AccumulationTraits;
// 全特化:int
template <>
struct AccumulationTraits {
using AccT = int;
static constexpr AccT zero() { return 0; }
};
// 全特化:float
template <>
struct AccumulationTraits {
using AccT = double; // 累積用雙精度避免溢出
static constexpr AccT zero() { return 0.0; }
};
struct SumPolicy {
template
static void accumulate(T1& total, const T2& value) {
total += value;
}
};
struct MultPolicy {
template
static void accumulate(T1& total, const T2& value) {
total *= value;
}
};
template , typename Policy = SumPolicy>
class Accum {
public:
using AccT = typename Traits::AccT;
static AccT accum(const T* beg, const T* end) {
AccT total = Traits::zero();
while (beg != end) {
Policy::accumulate(total, *beg);
++beg;
}
return total;
}
};
// 使用示例
int arr[] = {1,2,3,4,5};
int sum = Accum::accum(arr, arr+5); // 15
double prod = Accum, MultPolicy>::accum(arr, arr+5); // 120
全特化 → 偏特化 → 主模板,匹配規則與重載解析一致,無需人工干預。實現:根據類型/條件差異給出不同實現,極大提升擴展性。