sizeof 基本規則
- 編譯期運算符,返回類型或表達式的字節大小
- 不計算表達式值,僅推導類型
- 對數組參數退化為指針,
sizeof(arr) 在函數內返回指針大小
測試代碼與輸出(VS2013 x64)
#include <iostream>
using namespace std;
void TestSizeof() {
cout << "char: " << sizeof(char) << "\n"; // 1
cout << "short: " << sizeof(short) << "\n"; // 2
cout << "int: " << sizeof(int) << "\n"; // 4
cout << "float: " << sizeof(float) << "\n"; // 4
cout << "double: " << sizeof(double) << "\n"; // 8
cout << "char*: " << sizeof(char*) << "\n"; // 8 (64位)
cout << "string literal: " << sizeof("hello") << "\n"; // 6 (含\0)
char arr[] = "hello";
cout << "char[]: " << sizeof(arr) << "\n"; // 6
cout << "char[] as param: " << sizeof([](char s[]){return sizeof(s);}(arr)) << "\n"; // 8
}
關鍵現象解析
| 現象 | 原因 |
空類 sizeof(Empty) = 1 | 確保每個對象有唯一地址,new Empty 能分配非零內存 |
| 空基類優化 (EBO) | 派生類若無數據成員,繼承空基類不增加大小 |
| 內存對齊 | 成員偏移為其大小倍數;結構體總大小為最大對齊數倍數;#pragma pack(n) 可改變 |
| 虛函數表指針 (vptr) | 含虛函數的類對象隱含 vptr,大小 = 指針大小(4/8字節) |
對齊示例
class A { char a; }; // sizeof=1
class B { char a; short b; }; // sizeof=4 (對齊到2)
class C { char a; short b; double c; }; // sizeof=16 (對齊到8)
#pragma pack(1)
class D { char a; short b; double c; }; // sizeof=11 (無填充)
#pragma pack()
多態類大小
class V1 { virtual void f(); }; // sizeof = 8 (vptr)
class V2 { virtual void f(); virtual void g(); }; // sizeof = 8 (同一vptr)
class V3 { char c; virtual void f(); }; // sizeof = 16 (c + padding + vptr)
最佳實踐
- 頻繁訪問的成員放前面(利用緩存局部性)
- 大數據成員優先聲明(減少填充)
- 避免不必要的虛函數(增加對象大小)
- 用
alignas (C++11) 顯式控制對齊