需求分析
- 基類 `Person`:姓名、性別、年齡 (public);靜態 `males`、`females` 統計計數。
- 派生類 `Teacher`:繼承 `Person`,增加工號、工資。
- 派生類 `Student`:繼承 `Person`,增加學號、班級。
- `main` 創建對象、統計男女總數、打印所有信息。
關鍵設計要點
- 靜態成員定義分離:類內聲明 `static int males;`,類外**必須**定義 `int Person::males = 0;` (否則鏈接錯誤)。
- 構造函數統計邏輯:在 `Person` 構造函數中根據性別遞增計數器,派生類構造函數調用基類構造函數自動統計。
- 虛析構函數:基類析構函數聲明 `virtual`,確保派生類對象經基類指針刪除時正確調用派生類析構。
- 輸出運算符重載 / 統一打印接口:避免 `main` 中重複 `cout` 代碼。
完整標準代碼
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Person {
public:
string name, sex;
int age;
static int males, females;
Person(string n, string s, int a) : name(n), sex(s), age(a) {
if (sex == "male" || sex == "男") males++;
else if (sex == "female" || sex == "女") females++;
}
virtual ~Person() {} // 虛析構
virtual void print() const { // 多態打印接口
cout << "Name:" << name << " Sex:" << sex << " Age:" << age;
}
};
int Person::males = 0; // 類外定義
int Person::females = 0;
class Teacher : public Person {
string workNo, salary;
public:
Teacher(string n, string s, int a, string w, string sal)
: Person(n, s, a), workNo(w), salary(sal) {}
void print() const override {
Person::print();
cout << " WorkNo:" << workNo << " Salary:" << salary << endl;
}
};
class Student : public Person {
int stuNo, classNo;
public:
Student(string n, string s, int a, int sn, int cn)
: Person(n, s, a), stuNo(sn), classNo(cn) {}
void print() const override {
Person::print();
cout << " StuNo:" << stuNo << " Class:" << classNo << endl;
}
};
int main() {
vector people = {
new Student("Alice", "女", 13, 1, 1),
new Student("Bob", "男", 14, 2, 2),
new Teacher("Charlie", "男", 36, "T001", "8000"),
new Teacher("Diana", "女", 38, "T002", "9000")
};
cout << "=== All People ===" << endl;
for (auto p : people) p->print();
cout << "\nMales: " << Person::males << ", Females: " << Person::females << endl;
for (auto p : people) delete p; // 釋放內存
return 0;
}
常見錯誤避坑
- 靜態成員僅聲明未定義 → 鏈接錯誤 `undefined reference to Person::males`。
- 性別字符串比較硬編碼 (`"nan"`/`"nv"`),建議用 `enum class Gender { Male, Female }` 類型安全。
- 派生類構造函數未顯式調用基類構造函數 → 基類成員未初始化、統計遺漏。
- 缺少虛析構 → 內存洩漏/行為未定義。