C++ 中 struct 與 class 的用法與區別
1. 概述
在 C++ 中,struct 與 class 都可以用來定義用户自定義類型(User-Defined Types)。
二者在語法能力上幾乎完全相同,都可以:
- 定義成員變量
- 定義成員函數
- 構造函數 / 析構函數
- 訪問修飾符(public / private / protected)
- 繼承、多態
- 模板化
唯一真正的語法差異只有兩點:默認訪問權限與默認繼承方式不同。
2. struct 與 class 的唯二語法差異
2.1 默認成員訪問權限不同
|
類型
|
默認成員權限
|
|
|
|
|
|
|
示例:
struct A {
int x; // 默認 public
};
class B {
int x; // 默認 private
};
2.2 默認繼承方式不同
|
繼承類型
|
使用 struct
|
使用 class
|
|
默認繼承方式
|
|
|
示例:
struct Base {};
struct Derived1 : Base {}; // 默認 public 繼承
class Base2 {};
class Derived2 : Base2 {}; // 默認 private 繼承
3. struct 與 class 其他方面完全一致
以下方面 struct 與 class 完全沒有語法區別:
- ✔ 可以定義成員函數
- ✔ 可以定義構造/析構函數
- ✔ 可以繼承 / 多態
- ✔ 可以模板化
- ✔ 可以有 private/protected/public
- ✔ 都可以作為面向對象編程的基本構件
- ✔ 都可以用於封裝數據與行為
示例:struct 一樣可以有複雜行為:
struct Foo {
Foo() {}
void run() {}
private:
int data;
};
而 class 一樣可以是純數據載體:
class Point {
public:
int x;
int y;
};
4. 使用上的習慣(行業廣泛遵循)
雖然語法等價,但開發中通常遵循以下約定:
4.1 struct 用於“數據結構”
特點:
- 成員默認 public,更適合公開的數據載體
- 更傾向於作為 POD(Plain Old Data)
- 常用於:
- 函數返回結構體
- 配置參數
- 輕量數據結構
示例:
struct Vec3 {
float x, y, z;
};
4.2 class 用於“面向對象的封裝”
特點:
- 成員多數為 private
- 強調封裝性與行為邏輯
- 常用於:
- 對象抽象(Student、Car 等)
- 封裝複雜行為
- 多態體系
示例:
class Student {
public:
void study();
private:
std::string name;
int age;
};
5. 使用注意事項
5.1 注意默認繼承方式導致的 BUG
class Base {};
class Derived : Base {}; // 默認 private,會導致基類成員不可訪問
若你期望 public 繼承,一定要寫:
class Derived : public Base {};
5.2 使用 struct + private 容易造成誤解
雖然合法,但不符合常規閲讀習慣:
struct Foo {
private:
int x; // 不推薦:struct+private 容易誤導讀者
};
5.3 struct 並不等於 POD(Plain Old Data)
POD 是否成立取決於類型特徵,與是否為 struct/class 無關。
5.4 C 的 struct ≠ C++ 的 struct
C 語言的 struct:
- 不能有成員函數
- 不能有訪問修飾符
- 不能繼承
C++ 中 struct 和 class 完全等價,只是默認權限不同。
6. 示例代碼總結
struct(適合“數據結構”)
struct PersonInfo {
std::string name;
int age;
double height;
};
class(適合“封裝對象”)
class Person {
public:
Person(std::string name, int age) : name(name), age(age) {}
void introduce();
private:
std::string name;
int age;
};
7. 總結(面試高頻答案)
C++ 中 struct 與 class 的唯二區別是:
- 默認成員權限不同:struct 默認 public,class 默認 private。
- 默認繼承方式不同:struct 默認 public 繼承,class 默認 private 繼承。
除此之外二者完全一致。
struct 多用於數據載體,class 多用於封裝對象行為,這是編碼習慣而非語法規定。