C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)

📣📣📣📣📣📣📣📣

✏️作者主页:瑶池酒剑仙

📋 系列专栏:C++实战宝典

🌲上一篇: C++并发编程完全指南:从多线程到无锁并发的实战宝典

📣📣📣📣📣📣📣📣

🎍逐梦编程,让中华屹立世界之巅。
🎍简单的事情重复做,重复的事情用心做,用心的事情坚持做;

文章目录


引言:面向对象编程的基石

C++是一门面向对象的编程语言,而类和对象是其核心精髓所在。类(Class)是创建对象的蓝图,它封装了数据和行为;对象(Object)则是类的具体实例,在内存中占据实际空间。面向对象编程的三大特性------封装、继承、多态,都通过类和对象得以实现。掌握类和对象,就等于掌握了C++程序设计的半壁江山。本文将从类的定义开始,深入剖析构造函数、析构函数、this指针、静态成员、友元函数等核心概念,并结合内存布局、设计模式等高级话题,带您全面理解C++的面向对象机制。


一、类的基本概念

1.1 类的定义与对象的创建

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

// 类的定义
class Student {
public:      // 公有访问权限
    string name;
    int age;
    float score;
    
    // 成员函数(方法)
    void display() {
        cout << "姓名: " << name << ", 年龄: " << age << ", 成绩: " << score << endl;
    }
    
    void study(int hours) {
        cout << name << " 学习了 " << hours << " 小时" << endl;
        score += hours * 0.5;
    }
};

void classBasics() {
    // 创建对象(栈上分配)
    Student stu1;
    stu1.name = "张三";
    stu1.age = 18;
    stu1.score = 85.5;
    stu1.display();
    stu1.study(3);
    stu1.display();
    
    // 创建对象数组
    Student classRoom[3];
    classRoom[0].name = "李四";
    classRoom[1].name = "王五";
    classRoom[2].name = "赵六";
    
    // 指针访问成员(使用->操作符)
    Student* ptr = &stu1;
    ptr->study(2);
    
    // 动态创建对象(堆上分配)
    Student* pStu = new Student;
    pStu->name = "动态学生";
    pStu->age = 20;
    pStu->score = 90.0;
    pStu->display();
    delete pStu;  // 记得释放内存
}

// 访问权限演示
class AccessDemo {
private:     // 私有:只能在类内部访问
    int privateData;
    
protected:   // 受保护:类内部和派生类可访问
    int protectedData;
    
public:      // 公有:任何地方都可访问
    int publicData;
    
    void setPrivate(int value) {
        privateData = value;  // 类内部可访问私有成员
    }
    
    int getPrivate() const {
        return privateData;
    }
};

void accessModifiers() {
    AccessDemo obj;
    // obj.privateData = 10;    // 错误!私有成员不可访问
    // obj.protectedData = 20;  // 错误!受保护成员不可直接访问
    obj.publicData = 30;        // 正确
    
    obj.setPrivate(100);        // 通过公有接口访问私有成员
    cout << "私有数据: " << obj.getPrivate() << endl;
}

1.2 成员函数的定义方式

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

// 方式1:类内定义(隐式内联)
class Point1 {
private:
    int x, y;
public:
    void setX(int value) { x = value; }      // 类内定义
    void setY(int value) { y = value; }
    int getX() { return x; }
    int getY() { return y; }
};

// 方式2:类外定义(使用作用域解析符::)
class Point2 {
private:
    int x, y;
public:
    void setX(int value);
    void setY(int value);
    int getX() const;
    int getY() const;
};

// 类外定义成员函数
void Point2::setX(int value) {
    x = value;
}

void Point2::setY(int value) {
    y = value;
}

int Point2::getX() const {
    return x;
}

int Point2::getY() const {
    return y;
}

// 方式3:分文件组织(推荐)
// Point.h - 头文件
/*
#ifndef POINT_H
#define POINT_H

class Point {
private:
    int x, y;
public:
    void setX(int value);
    void setY(int value);
    int getX() const;
    int getY() const;
};

#endif
*/

// Point.cpp - 实现文件
/*
#include "Point.h"

void Point::setX(int value) { x = value; }
void Point::setY(int value) { y = value; }
int Point::getX() const { return x; }
int Point::getY() const { return y; }
*/

void memberFunctionDefinition() {
    Point2 p;
    p.setX(10);
    p.setY(20);
    cout << "Point: (" << p.getX() << ", " << p.getY() << ")" << endl;
}

二、构造函数与析构函数

2.1 构造函数详解

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

class Book {
private:
    string title;
    string author;
    double price;
    int pages;
    
public:
    // 1. 默认构造函数(无参数)
    Book() {
        title = "未知";
        author = "匿名";
        price = 0.0;
        pages = 0;
        cout << "默认构造函数被调用" << endl;
    }
    
    // 2. 带参数的构造函数
    Book(const string& t, const string& a, double p, int pg) {
        title = t;
        author = a;
        price = p;
        pages = pg;
        cout << "参数化构造函数被调用: " << title << endl;
    }
    
    // 3. 使用初始化列表(更高效)
    Book(const string& t, const string& a) 
        : title(t), author(a), price(0.0), pages(0) {
        cout << "初始化列表构造函数: " << title << endl;
    }
    
    // 4. 委托构造函数(C++11)
    Book(const string& t) : Book(t, "未知", 0.0, 0) {
        cout << "委托构造函数" << endl;
    }
    
    // 5. 拷贝构造函数
    Book(const Book& other) 
        : title(other.title), author(other.author), 
          price(other.price), pages(other.pages) {
        cout << "拷贝构造函数: " << title << endl;
    }
    
    void display() const {
        cout << "《" << title << "》 作者:" << author 
             << ", 价格:" << price << ", 页数:" << pages << endl;
    }
};

void constructorDemo() {
    cout << "=== 构造函数演示 ===" << endl;
    
    Book b1;                           // 默认构造
    Book b2("C++ Primer", "Lippman", 128.0, 1200);  // 参数化构造
    Book b3("Effective C++", "Meyers"); // 初始化列表构造
    Book b4("Design Patterns");         // 委托构造
    Book b5(b2);                        // 拷贝构造
    
    b1.display();
    b2.display();
    b3.display();
    b4.display();
    b5.display();
}

// 构造函数的重载
class Date {
private:
    int year, month, day;
    
public:
    Date() : year(1970), month(1), day(1) {}
    
    Date(int y, int m, int d) : year(y), month(m), day(d) {}
    
    Date(int y) : year(y), month(1), day(1) {}
    
    // 使用默认参数
    Date(int y, int m = 1, int d = 1) : year(y), month(m), day(d) {}
    // 注意:带有默认参数的构造函数可能与无参构造产生歧义
    
    void show() const {
        cout << year << "-" << month << "-" << day << endl;
    }
};

2.2 析构函数

cpp 复制代码
class ResourceManager {
private:
    char* buffer;
    size_t size;
    
public:
    // 构造函数:分配资源
    ResourceManager(size_t sz) : size(sz) {
        buffer = new char[size];
        cout << "分配 " << size << " 字节内存" << endl;
    }
    
    // 析构函数:释放资源(~类名,无参数,无返回值)
    ~ResourceManager() {
        delete[] buffer;
        cout << "释放 " << size << " 字节内存" << endl;
    }
    
    void setData(const char* str) {
        strncpy(buffer, str, size - 1);
        buffer[size - 1] = '\0';
    }
    
    void display() const {
        cout << "数据: " << buffer << endl;
    }
};

// 演示析构函数自动调用
void destructorDemo() {
    cout << "进入函数" << endl;
    
    ResourceManager res(100);
    res.setData("Hello, RAII!");
    res.display();
    
    cout << "即将离开函数" << endl;
    // res的析构函数自动调用,释放内存
}

// 析构函数调用顺序(后创建先析构)
class OrderTest {
private:
    int id;
    
public:
    OrderTest(int i) : id(i) {
        cout << "对象 " << id << " 构造" << endl;
    }
    
    ~OrderTest() {
        cout << "对象 " << id << " 析构" << endl;
    }
};

void destructorOrder() {
    OrderTest o1(1);
    OrderTest o2(2);
    {
        OrderTest o3(3);
        OrderTest o4(4);
    }  // o4, o3在此析构
    OrderTest o5(5);
}  // o5, o2, o1依次析构

// 虚析构函数(用于多态场景)
class Base {
public:
    virtual ~Base() {
        cout << "Base析构" << endl;
    }
};

class Derived : public Base {
private:
    int* data;
public:
    Derived() : data(new int[100]) {}
    ~Derived() override {
        delete[] data;
        cout << "Derived析构" << endl;
    }
};

void virtualDestructorDemo() {
    Base* ptr = new Derived();
    delete ptr;  // 如果Base析构不是virtual,则Derived析构不会被调用
}

2.3 拷贝构造函数与深拷贝

cpp 复制代码
// 浅拷贝问题演示
class ShallowCopy {
private:
    int* data;
    
public:
    ShallowCopy(int value) {
        data = new int(value);
        cout << "构造: " << *data << endl;
    }
    
    // 默认拷贝构造函数执行浅拷贝
    // 两个对象的data指针指向同一块内存
    ~ShallowCopy() {
        delete data;
        cout << "析构" << endl;
    }
    
    int getValue() const { return *data; }
};

void shallowCopyProblem() {
    ShallowCopy obj1(42);
    ShallowCopy obj2 = obj1;  // 浅拷贝,两个指针指向同一内存
    // 析构时会double free,程序崩溃!
}

// 深拷贝:正确实现
class DeepCopy {
private:
    int* data;
    
public:
    DeepCopy(int value) {
        data = new int(value);
        cout << "构造: " << *data << endl;
    }
    
    // 深拷贝构造函数
    DeepCopy(const DeepCopy& other) {
        data = new int(*other.data);  // 重新分配内存
        cout << "深拷贝构造: " << *data << endl;
    }
    
    // 深拷贝赋值运算符
    DeepCopy& operator=(const DeepCopy& other) {
        if (this != &other) {
            delete data;
            data = new int(*other.data);
            cout << "深拷贝赋值: " << *data << endl;
        }
        return *this;
    }
    
    ~DeepCopy() {
        delete data;
        cout << "析构: " << (data ? "释放" : "空指针") << endl;
    }
    
    void setValue(int value) { *data = value; }
    int getValue() const { return *data; }
};

void deepCopyDemo() {
    DeepCopy a(100);
    DeepCopy b = a;      // 深拷贝构造
    DeepCopy c(200);
    c = a;               // 深拷贝赋值
    
    b.setValue(999);
    cout << "a: " << a.getValue() << ", b: " << b.getValue() << endl;
    // a和b独立,互不影响
}

三、this指针与静态成员

3.1 this指针详解

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

class Counter {
private:
    int count;
    
public:
    Counter() : count(0) {}
    
    // this指针指向当前对象
    Counter& increment() {
        count++;
        return *this;  // 返回当前对象的引用,支持链式调用
    }
    
    Counter& decrement() {
        count--;
        return *this;
    }
    
    void display() const {
        cout << "当前计数: " << count << endl;
    }
    
    // 参数与成员同名时使用this区分
    void setCount(int count) {
        this->count = count;  // this->count是成员变量,count是参数
    }
};

void thisPointerDemo() {
    Counter c;
    // 链式调用(方法级联)
    c.increment().increment().decrement().increment();
    c.display();  // 计数: 2
}

// 使用this指针实现比较
class Person {
private:
    string name;
    int age;
    
public:
    Person(const string& n, int a) : name(n), age(a) {}
    
    // const成员函数中的this是const指针
    bool isOlderThan(const Person& other) const {
        return this->age > other.age;  // this->可省略
    }
    
    Person* getThis() {
        return this;  // 返回当前对象的指针
    }
    
    const Person* getThis() const {
        return this;
    }
};

void personCompare() {
    Person alice("Alice", 25);
    Person bob("Bob", 30);
    
    if (bob.isOlderThan(alice)) {
        cout << "Bob比Alice年龄大" << endl;
    }
    
    // this指针的值等于对象的地址
    cout << "对象地址: " << &alice << endl;
    cout << "this指针: " << alice.getThis() << endl;
}

3.2 静态成员变量

cpp 复制代码
class Employee {
private:
    string name;
    int id;
    
    // 静态成员变量:属于类,不属于任何对象
    static int totalEmployees;      // 声明
    static int nextId;              // 用于生成唯一ID
    
public:
    Employee(const string& n) : name(n) {
        id = nextId++;
        totalEmployees++;
        cout << "创建员工: " << name << ", ID: " << id 
             << ", 总人数: " << totalEmployees << endl;
    }
    
    ~Employee() {
        totalEmployees--;
        cout << "销毁员工: " << name << ", 剩余: " << totalEmployees << endl;
    }
    
    // 静态成员函数:只能访问静态成员
    static int getTotalEmployees() {
        return totalEmployees;
    }
    
    static void showStatistics() {
        cout << "=== 员工统计 ===" << endl;
        cout << "总人数: " << totalEmployees << endl;
        cout << "下一个ID: " << nextId << endl;
    }
    
    void display() const {
        cout << "员工: " << name << ", ID: " << id << endl;
    }
};

// 静态成员变量的定义和初始化(必须在类外)
int Employee::totalEmployees = 0;
int Employee::nextId = 1;

void staticMemberDemo() {
    cout << "初始总人数: " << Employee::getTotalEmployees() << endl;
    
    Employee e1("张三");
    Employee e2("李四");
    Employee e3("王五");
    
    Employee::showStatistics();  // 通过类名调用静态函数
    
    {
        Employee e4("赵六");
        cout << "当前总人数: " << Employee::getTotalEmployees() << endl;
    }  // e4被销毁
    
    cout << "最终总人数: " << Employee::getTotalEmployees() << endl;
}

// 静态常量成员
class MathConstants {
public:
    static const double PI;           // 在类内声明
    static constexpr double E = 2.718281828459045;  // C++11字面量常量
    
    static double circleArea(double radius) {
        return PI * radius * radius;
    }
};

// 类外定义静态常量成员
const double MathConstants::PI = 3.141592653589793;

3.3 静态成员函数

cpp 复制代码
// 静态成员函数的特点和使用场景
class Database {
private:
    static Database* instance;
    string connectionString;
    bool connected;
    
    // 私有构造函数(单例模式)
    Database() : connectionString("default"), connected(false) {}
    
public:
    // 禁止拷贝
    Database(const Database&) = delete;
    Database& operator=(const Database&) = delete;
    
    // 静态方法获取单例实例
    static Database& getInstance() {
        if (instance == nullptr) {
            instance = new Database();
        }
        return *instance;
    }
    
    static void setConnection(const string& conn) {
        getInstance().connectionString = conn;
    }
    
    void connect() {
        cout << "连接到: " << connectionString << endl;
        connected = true;
    }
    
    void disconnect() {
        cout << "断开连接" << endl;
        connected = false;
    }
    
    static void cleanup() {
        delete instance;
        instance = nullptr;
    }
};

// 初始化静态成员
Database* Database::instance = nullptr;

void staticFunctionDemo() {
    // 通过类名调用静态方法
    Database::setConnection("mysql://localhost:3306/mydb");
    
    Database& db = Database::getInstance();
    db.connect();
    db.disconnect();
    
    Database::cleanup();
}

// 静态成员函数的限制
class StaticTest {
private:
    int instanceData;
    static int staticData;
    
public:
    void instanceMethod() {
        instanceData = 10;    // 可以访问实例数据
        staticData = 20;      // 可以访问静态数据
    }
    
    static void staticMethod() {
        // instanceData = 10;    // 错误!不能访问非静态成员
        staticData = 20;        // 只能访问静态成员
        
        // 不能使用this指针(没有this)
        // 可以创建对象来访问非静态成员
        StaticTest obj;
        obj.instanceData = 30;
    }
};

int StaticTest::staticData = 0;

四、常量成员与友元

4.1 const成员函数与mutable

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

class ConstDemo {
private:
    int data;
    mutable int cacheData;  // mutable成员可在const函数中修改
    mutable int accessCount;
    
public:
    ConstDemo(int d) : data(d), cacheData(0), accessCount(0) {}
    
    // const成员函数:承诺不修改对象状态
    int getData() const {
        // data = 10;           // 错误!不能修改普通成员
        accessCount++;          // 可以修改mutable成员
        return data;
    }
    
    // 非const成员函数
    void setData(int d) {
        data = d;
    }
    
    // const重载
    int& getRef() {
        cout << "非const版本" << endl;
        return data;
    }
    
    const int& getRef() const {
        cout << "const版本" << endl;
        return data;
    }
    
    int getAccessCount() const {
        return accessCount;
    }
};

void constMemberDemo() {
    // const对象只能调用const成员函数
    const ConstDemo constObj(100);
    cout << "const对象读取: " << constObj.getData() << endl;
    // constObj.setData(200);   // 错误!const对象不能调用非const函数
    
    ConstDemo nonConstObj(200);
    nonConstObj.setData(300);      // 调用非const版本
    int& ref = nonConstObj.getRef();  // 非const版本
    
    const ConstDemo& constRef = nonConstObj;
    constRef.getRef();              // const版本
}

// 成员初始化列表中的const成员
class ConstMember {
private:
    const int id;           // const成员必须在初始化列表中初始化
    const string name;
    static const int MAX_COUNT = 100;  // 静态const可在类内初始化
    
public:
    ConstMember(int i, const string& n) : id(i), name(n) {
        // id = i;   // 错误!不能在构造函数体内赋值
    }
    
    void display() const {
        cout << "ID: " << id << ", Name: " << name 
             << ", MAX: " << MAX_COUNT << endl;
    }
};

4.2 友元函数与友元类

cpp 复制代码
// 前向声明
class Vector2D;

// 友元函数
class Vector2D {
private:
    double x, y;
    
public:
    Vector2D(double x = 0, double y = 0) : x(x), y(y) {}
    
    // 声明友元函数(非成员函数可以访问私有成员)
    friend Vector2D operator+(const Vector2D& a, const Vector2D& b);
    friend ostream& operator<<(ostream& os, const Vector2D& v);
    
    // 声明其他类的成员函数为友元
    friend void Matrix::transform(Vector2D& v);  // 前向声明需要
    
    // 普通成员函数
    void display() const {
        cout << "(" << x << ", " << y << ")" << endl;
    }
};

// 友元函数实现
Vector2D operator+(const Vector2D& a, const Vector2D& b) {
    return Vector2D(a.x + b.x, a.y + b.y);  // 可直接访问私有成员
}

ostream& operator<<(ostream& os, const Vector2D& v) {
    os << "(" << v.x << ", " << v.y << ")";
    return os;
}

// 友元类
class Matrix {
private:
    double data[2][2];
    
public:
    Matrix(double a=1, double b=0, double c=0, double d=1) {
        data[0][0] = a; data[0][1] = b;
        data[1][0] = c; data[1][1] = d;
    }
    
    // 声明友元类
    friend class VectorTransformer;
};

// 友元类可以访问Matrix的私有成员
class VectorTransformer {
public:
    static Vector2D transform(const Matrix& m, const Vector2D& v) {
        double x = m.data[0][0] * v.x + m.data[0][1] * v.y;
        double y = m.data[1][0] * v.x + m.data[1][1] * v.y;
        return Vector2D(x, y);
    }
};

void friendDemo() {
    Vector2D v1(3, 4);
    Vector2D v2(1, 2);
    Vector2D v3 = v1 + v2;
    
    cout << "v1 = " << v1 << endl;
    cout << "v2 = " << v2 << endl;
    cout << "v1 + v2 = " << v3 << endl;
    
    Matrix m(2, 0, 0, 2);  // 缩放2倍
    Vector2D transformed = VectorTransformer::transform(m, v1);
    cout << "变换后: " << transformed << endl;
}

// 友元的注意事项
class FriendNote {
private:
    int secret;
    
    // 友元关系不能继承
    friend class FriendClass;
    // 友元关系是单向的(A是B的友元,不代表B是A的友元)
    // 友元关系不能被传递(A是B的友元,B是C的友元,不代表A是C的友元)
};

五、继承与多态基础

5.1 继承的基本语法

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/11
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

// 基类
class Animal {
protected:   // 派生类可访问
    string name;
    int age;
    
public:
    Animal(const string& n, int a) : name(n), age(a) {
        cout << "Animal构造: " << name << endl;
    }
    
    virtual ~Animal() {
        cout << "Animal析构: " << name << endl;
    }
    
    virtual void speak() const {
        cout << name << " 发出动物叫声" << endl;
    }
    
    void eat() const {
        cout << name << " 正在吃东西" << endl;
    }
    
    string getName() const { return name; }
};

// 公有继承
class Dog : public Animal {
private:
    string breed;  // 品种
    
public:
    Dog(const string& n, int a, const string& b) 
        : Animal(n, a), breed(b) {
        cout << "Dog构造: " << name << " (" << breed << ")" << endl;
    }
    
    ~Dog() override {
        cout << "Dog析构: " << name << endl;
    }
    
    void speak() const override {
        cout << name << " 汪汪汪!" << endl;
    }
    
    void wagTail() const {
        cout << name << " 摇尾巴" << endl;
    }
};

// 私有继承
class PrivateDerived : private Animal {
    // 基类的public/protected成员变成private
public:
    using Animal::getName;  // 使getName在public区域可见
};

void inheritanceDemo() {
    cout << "=== 继承演示 ===" << endl;
    
    Dog dog("旺财", 3, "金毛");
    dog.speak();    // 重写的方法
    dog.eat();      // 继承的方法
    dog.wagTail();  // 派生类自己的方法
    
    // 向上转型(派生类到基类)
    Animal* ptr = &dog;
    ptr->speak();   // 多态:调用Dog的speak
    ptr->eat();     // 调用Animal的eat
}

// 继承中的构造函数和析构函数调用顺序
class Base1 {
public:
    Base1() { cout << "Base1构造" << endl; }
    ~Base1() { cout << "Base1析构" << endl; }
};

class Base2 {
public:
    Base2() { cout << "Base2构造" << endl; }
    ~Base2() { cout << "Base2析构" << endl; }
};

class Derived1 : public Base1, public Base2 {
private:
    Base1 member1;
    Base2 member2;
    
public:
    Derived1() {
        cout << "Derived1构造" << endl;
    }
    ~Derived1() {
        cout << "Derived1析构" << endl;
    }
};

void orderDemo() {
    Derived1 d;
    // 构造顺序:基类(按声明顺序)-> 成员(按声明顺序)-> 派生类
    // 析构顺序相反
}

5.2 虚函数与多态

cpp 复制代码
// 虚函数表示例
class Shape {
public:
    virtual double area() const = 0;  // 纯虚函数,抽象类
    virtual void draw() const {
        cout << "绘制形状" << endl;
    }
    virtual ~Shape() = default;
};

class Circle : public Shape {
private:
    double radius;
    
public:
    Circle(double r) : radius(r) {}
    
    double area() const override {
        return 3.14159 * radius * radius;
    }
    
    void draw() const override {
        cout << "绘制圆形,半径: " << radius << endl;
    }
};

class Rectangle : public Shape {
private:
    double width, height;
    
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    double area() const override {
        return width * height;
    }
    
    void draw() const override {
        cout << "绘制矩形,宽: " << width << ", 高: " << height << endl;
    }
};

void polymorphismDemo() {
    vector<Shape*> shapes;
    shapes.push_back(new Circle(5));
    shapes.push_back(new Rectangle(4, 6));
    shapes.push_back(new Circle(3));
    
    for (Shape* s : shapes) {
        s->draw();
        cout << "面积: " << s->area() << endl;
    }
    
    // 释放内存
    for (Shape* s : shapes) {
        delete s;
    }
}

// 虚函数表(vtable)的概念
class VTableDemo {
public:
    virtual void func1() { cout << "VTableDemo::func1" << endl; }
    virtual void func2() { cout << "VTableDemo::func2" << endl; }
    void func3() { cout << "VTableDemo::func3 (非虚)" << endl; }
};

class DerivedVTable : public VTableDemo {
public:
    void func1() override { cout << "DerivedVTable::func1" << endl; }
    virtual void func4() { cout << "DerivedVTable::func4" << endl; }
};

void vtableExplanation() {
    VTableDemo* ptr = new DerivedVTable();
    ptr->func1();  // 通过虚表调用派生类版本
    ptr->func2();  // 通过虚表调用基类版本
    ptr->func3();  // 非虚函数,编译时绑定
    delete ptr;
}

六、对象内存模型

6.1 对象的内存布局

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/04/04
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

#include <cstddef>

// 空类的大小
class Empty {};

// 带成员变量的类
class DataMembers {
private:
    char c;      // 1字节
    int i;       // 4字节(可能对齐到4)
    double d;    // 8字节
    // 实际大小可能大于1+4+8=13,因为有内存对齐
};

// 带虚函数的类(有虚表指针)
class WithVtable {
public:
    int x;
    virtual void func() {}
};

// 继承中的内存布局
class BaseLayout {
public:
    int baseData;
    virtual void baseFunc() {}
};

class DerivedLayout : public BaseLayout {
public:
    int derivedData;
    void baseFunc() override {}
    virtual void derivedFunc() {}
};

void memoryLayout() {
    cout << "=== 对象内存大小 ===" << endl;
    cout << "Empty类大小: " << sizeof(Empty) << " 字节" << endl;  // 1字节(占位)
    cout << "DataMembers类大小: " << sizeof(DataMembers) << " 字节" << endl;
    cout << "WithVtable类大小: " << sizeof(WithVtable) << " 字节" << endl;
    cout << "BaseLayout类大小: " << sizeof(BaseLayout) << " 字节" << endl;
    cout << "DerivedLayout类大小: " << sizeof(DerivedLayout) << " 字节" << endl;
    
    // 成员偏移量
    DataMembers obj;
    cout << "\n=== 成员偏移量 ===" << endl;
    cout << "c的偏移: " << offsetof(DataMembers, c) << endl;
    cout << "i的偏移: " << offsetof(DataMembers, i) << endl;
    cout << "d的偏移: " << offsetof(DataMembers, d) << endl;
}

// 对象的内存分配
class MemoryObject {
public:
    int a;
    int b;
    static int staticValue;  // 静态成员不属于对象
    
    void method1() {}   // 函数代码不在对象中
    virtual void vmethod() {}  // 虚函数表指针在对象中
};

int MemoryObject::staticValue = 0;

void memoryAllocation() {
    // 栈上分配
    MemoryObject stackObj;
    stackObj.a = 10;
    
    // 堆上分配
    MemoryObject* heapObj = new MemoryObject();
    heapObj->b = 20;
    
    // 静态存储区
    static MemoryObject staticObj;
    
    delete heapObj;
}

6.2 对齐与填充

cpp 复制代码
// 内存对齐控制
#pragma pack(push, 1)  // 按1字节对齐
struct PackedStruct {
    char c;
    int i;
    short s;
};
#pragma pack(pop)

struct DefaultStruct {
    char c;
    int i;
    short s;
};

// 手动对齐
struct AlignedStruct {
    char c;
    char padding1[3];  // 手动填充
    int i;
    short s;
    char padding2[2];  // 手动填充
};

void alignmentDemo() {
    cout << "\n=== 内存对齐对比 ===" << endl;
    cout << "默认对齐大小: " << sizeof(DefaultStruct) << " 字节" << endl;
    cout << "紧凑对齐(1字节): " << sizeof(PackedStruct) << " 字节" << endl;
    cout << "手动对齐: " << sizeof(AlignedStruct) << " 字节" << endl;
    
    // C++11 alignas指定对齐
    struct alignas(16) Aligned16 {
        char data[8];
    };
    cout << "16字节对齐: " << sizeof(Aligned16) << " 字节" << endl;
    cout << "对齐要求: " << alignof(Aligned16) << " 字节" << endl;
}

七、综合实战:简单的图书管理系统

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/05/10
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

#include <vector>
#include <algorithm>
#include <iomanip>

// 图书类
class Book {
private:
    string isbn;
    string title;
    string author;
    double price;
    int stock;
    static int totalBooks;
    
public:
    Book(const string& isbn, const string& title, 
         const string& author, double price, int stock)
        : isbn(isbn), title(title), author(author), 
          price(price), stock(stock) {
        totalBooks++;
    }
    
    ~Book() {
        totalBooks--;
    }
    
    // 拷贝构造(深拷贝)
    Book(const Book& other)
        : isbn(other.isbn), title(other.title),
          author(other.author), price(other.price), 
          stock(other.stock) {
        totalBooks++;
    }
    
    // 赋值运算符
    Book& operator=(const Book& other) {
        if (this != &other) {
            isbn = other.isbn;
            title = other.title;
            author = other.author;
            price = other.price;
            stock = other.stock;
        }
        return *this;
    }
    
    // getter方法
    string getIsbn() const { return isbn; }
    string getTitle() const { return title; }
    string getAuthor() const { return author; }
    double getPrice() const { return price; }
    int getStock() const { return stock; }
    
    void setStock(int s) { stock = s; }
    
    bool borrow() {
        if (stock > 0) {
            stock--;
            return true;
        }
        return false;
    }
    
    void returnBook() {
        stock++;
    }
    
    void display() const {
        cout << left << setw(15) << isbn
             << setw(25) << title
             << setw(15) << author
             << setw(8) << price
             << setw(6) << stock << endl;
    }
    
    static int getTotalBooks() {
        return totalBooks;
    }
    
    // 友元函数:比较运算符
    friend bool operator==(const Book& a, const Book& b) {
        return a.isbn == b.isbn;
    }
};

int Book::totalBooks = 0;

// 借阅记录类
class BorrowRecord {
private:
    string isbn;
    string borrower;
    time_t borrowDate;
    time_t returnDate;
    bool returned;
    
public:
    BorrowRecord(const string& isbn, const string& borrower)
        : isbn(isbn), borrower(borrower), 
          borrowDate(time(nullptr)), returned(false), returnDate(0) {}
    
    void returnBook() {
        returnDate = time(nullptr);
        returned = true;
    }
    
    void display() const {
        cout << "ISBN: " << isbn << ", 借阅人: " << borrower
             << ", 借阅时间: " << ctime(&borrowDate);
        if (returned) {
            cout << ", 归还时间: " << ctime(&returnDate);
        } else {
            cout << ", 状态: 未归还" << endl;
        }
    }
    
    bool isReturned() const { return returned; }
    string getIsbn() const { return isbn; }
};

// 图书馆类
class Library {
private:
    vector<Book> books;
    vector<BorrowRecord> records;
    mutable mutex mtx;  // 线程安全(演示用)
    
    // 查找图书(私有辅助函数)
    int findBook(const string& isbn) const {
        for (size_t i = 0; i < books.size(); ++i) {
            if (books[i].getIsbn() == isbn) {
                return i;
            }
        }
        return -1;
    }
    
public:
    // 添加图书
    void addBook(const Book& book) {
        lock_guard<mutex> lock(mtx);
        int index = findBook(book.getIsbn());
        if (index != -1) {
            // 已存在,增加库存
            books[index].setStock(books[index].getStock() + book.getStock());
            cout << "增加库存: " << book.getTitle() << endl;
        } else {
            books.push_back(book);
            cout << "添加新书: " << book.getTitle() << endl;
        }
    }
    
    // 删除图书
    bool removeBook(const string& isbn) {
        lock_guard<mutex> lock(mtx);
        auto it = find_if(books.begin(), books.end(),
            [&isbn](const Book& b) { return b.getIsbn() == isbn; });
        
        if (it != books.end()) {
            books.erase(it);
            cout << "删除图书: " << isbn << endl;
            return true;
        }
        return false;
    }
    
    // 借阅图书
    bool borrowBook(const string& isbn, const string& borrower) {
        lock_guard<mutex> lock(mtx);
        int index = findBook(isbn);
        
        if (index != -1 && books[index].borrow()) {
            records.emplace_back(isbn, borrower);
            cout << borrower << " 借阅成功: " << books[index].getTitle() << endl;
            return true;
        }
        cout << "借阅失败: 图书不存在或库存不足" << endl;
        return false;
    }
    
    // 归还图书
    bool returnBook(const string& isbn, const string& borrower) {
        lock_guard<mutex> lock(mtx);
        int index = findBook(isbn);
        
        if (index != -1) {
            books[index].returnBook();
            
            // 查找并更新借阅记录
            for (auto& record : records) {
                if (record.getIsbn() == isbn && !record.isReturned()) {
                    record.returnBook();
                    cout << borrower << " 归还成功: " << books[index].getTitle() << endl;
                    return true;
                }
            }
        }
        cout << "归还失败: 未找到借阅记录" << endl;
        return false;
    }
    
    // 搜索图书(const成员函数)
    void searchByTitle(const string& title) const {
        lock_guard<mutex> lock(mtx);
        cout << "\n=== 搜索结果(标题包含 \"" << title << "\")===" << endl;
        cout << left << setw(15) << "ISBN" << setw(25) << "书名"
             << setw(15) << "作者" << setw(8) << "价格" 
             << setw(6) << "库存" << endl;
        cout << string(70, '-') << endl;
        
        for (const auto& book : books) {
            if (book.getTitle().find(title) != string::npos) {
                book.display();
            }
        }
    }
    
    void displayAll() const {
        lock_guard<mutex> lock(mtx);
        cout << "\n=== 图书馆藏书 ===" << endl;
        cout << left << setw(15) << "ISBN" << setw(25) << "书名"
             << setw(15) << "作者" << setw(8) << "价格" 
             << setw(6) << "库存" << endl;
        cout << string(70, '-') << endl;
        
        for (const auto& book : books) {
            book.display();
        }
        cout << "\n总藏书种类: " << books.size() 
             << ", 总册数: " << Book::getTotalBooks() << endl;
    }
    
    void displayBorrowRecords() const {
        lock_guard<mutex> lock(mtx);
        cout << "\n=== 借阅记录 ===" << endl;
        for (const auto& record : records) {
            record.display();
        }
    }
};

void librarySystemDemo() {
    Library lib;
    
    // 添加图书
    lib.addBook(Book("978-7-121-12345-6", "C++ Primer", "Lippman", 128.0, 5));
    lib.addBook(Book("978-7-302-23456-7", "Effective C++", "Meyers", 89.0, 3));
    lib.addBook(Book("978-7-111-34567-8", "Design Patterns", "Gamma", 158.0, 2));
    lib.addBook(Book("978-7-121-12345-6", "C++ Primer", "Lippman", 128.0, 3)); // 增加库存
    
    // 显示藏书
    lib.displayAll();
    
    // 借阅图书
    lib.borrowBook("978-7-121-12345-6", "张三");
    lib.borrowBook("978-7-302-23456-7", "李四");
    lib.borrowBook("978-7-111-34567-8", "王五");
    lib.borrowBook("978-7-121-12345-6", "赵六");
    
    // 再次显示(库存变化)
    lib.displayAll();
    
    // 归还图书
    lib.returnBook("978-7-121-12345-6", "张三");
    
    // 搜索
    lib.searchByTitle("C++");
    
    // 显示借阅记录
    lib.displayBorrowRecords();
    
    // 显示统计信息
    cout << "\n=== 统计信息 ===" << endl;
    cout << "总图书种类: " << Book::getTotalBooks() << endl;
}

八、类设计最佳实践

8.1 设计原则与规范

代码如下(示例):

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/04/12
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   1.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

// 原则1:单一职责原则
// 好的设计:一个类只负责一件事
class Logger {
public:
    void log(const string& message) {
        cout << "[LOG] " << message << endl;
    }
};

class DataProcessor {
public:
    int process(int data) {
        return data * 2;
    }
};

// 不好的设计:一个类做太多事情
class BadDesign {
public:
    void log(const string& msg) { }
    int process(int data) { return data; }
    void saveToFile(const string& data) { }
    void sendNetwork(const string& data) { }
};

// 原则2:封装变化
class PaymentStrategy {  // 抽象接口
public:
    virtual void pay(double amount) = 0;
    virtual ~PaymentStrategy() = default;
};

class CreditCardPayment : public PaymentStrategy {
public:
    void pay(double amount) override {
        cout << "信用卡支付: " << amount << endl;
    }
};

class WeChatPayment : public PaymentStrategy {
public:
    void pay(double amount) override {
        cout << "微信支付: " << amount << endl;
    }
};

// 原则3:优先使用组合而非继承
class Engine {
public:
    void start() { cout << "引擎启动" << endl; }
};

class Car {
private:
    Engine engine;  // 组合
public:
    void start() {
        engine.start();
        cout << "汽车启动" << endl;
    }
};

// 原则4:接口隔离
class Printable {
public:
    virtual void print() = 0;
    virtual ~Printable() = default;
};

class Scannable {
public:
    virtual void scan() = 0;
    virtual ~Scannable() = default;
};

// 而不是定义一个巨大的接口

8.2 常见设计模式示例

cpp 复制代码
// 单例模式(线程安全)
class ThreadSafeSingleton {
private:
    static unique_ptr<ThreadSafeSingleton> instance;
    static mutex mtx;
    
    ThreadSafeSingleton() = default;
    
public:
    static ThreadSafeSingleton& getInstance() {
        if (instance == nullptr) {
            lock_guard<mutex> lock(mtx);
            if (instance == nullptr) {
                instance = unique_ptr<ThreadSafeSingleton>(new ThreadSafeSingleton());
            }
        }
        return *instance;
    }
    
    void doSomething() {
        cout << "Singleton instance working" << endl;
    }
    
    ThreadSafeSingleton(const ThreadSafeSingleton&) = delete;
    ThreadSafeSingleton& operator=(const ThreadSafeSingleton&) = delete;
};

unique_ptr<ThreadSafeSingleton> ThreadSafeSingleton::instance = nullptr;
mutex ThreadSafeSingleton::mtx;

// 工厂模式
class Product {
public:
    virtual void use() = 0;
    virtual ~Product() = default;
};

class ConcreteProductA : public Product {
public:
    void use() override { cout << "使用产品A" << endl; }
};

class ConcreteProductB : public Product {
public:
    void use() override { cout << "使用产品B" << endl; }
};

class Factory {
public:
    static unique_ptr<Product> createProduct(char type) {
        switch (type) {
            case 'A': return make_unique<ConcreteProductA>();
            case 'B': return make_unique<ConcreteProductB>();
            default: return nullptr;
        }
    }
};

// 建造者模式
class Computer {
private:
    string cpu;
    string memory;
    string storage;
    
public:
    void setCPU(const string& c) { cpu = c; }
    void setMemory(const string& m) { memory = m; }
    void setStorage(const string& s) { storage = s; }
    
    void show() const {
        cout << "Computer: CPU=" << cpu << ", Memory=" << memory 
             << ", Storage=" << storage << endl;
    }
};

class ComputerBuilder {
private:
    Computer computer;
    
public:
    ComputerBuilder& setCPU(const string& cpu) {
        computer.setCPU(cpu);
        return *this;
    }
    
    ComputerBuilder& setMemory(const string& memory) {
        computer.setMemory(memory);
        return *this;
    }
    
    ComputerBuilder& setStorage(const string& storage) {
        computer.setStorage(storage);
        return *this;
    }
    
    Computer build() {
        return computer;
    }
};

void designPatternsDemo() {
    // 单例
    ThreadSafeSingleton::getInstance().doSomething();
    
    // 工厂
    auto product = Factory::createProduct('A');
    product->use();
    
    // 建造者
    Computer pc = ComputerBuilder()
        .setCPU("Intel i7")
        .setMemory("16GB")
        .setStorage("512GB SSD")
        .build();
    pc.show();
}

九、总结

9.1 类和对象核心要点

概念 说明 要点
封装 数据隐藏 使用private/protected/public
继承 代码复用 支持单继承,可多重继承
多态 接口统一 虚函数、纯虚函数、抽象类
构造函数 对象初始化 可重载、初始化列表、委托构造
析构函数 资源释放 虚析构用于多态
this指针 对象自身 const成员函数中为const指针
静态成员 类级别共享 类外定义、静态函数只能访问静态成员
友元 特权访问 破坏封装,谨慎使用

9.2 完整示例:学生信息管理系统

cpp 复制代码
/*-----------------------------------【程序说明】----------------------------
*			 项目命题:   C++实战宝典
*			 代码所属:   瑶池酒剑仙(枫之剑客)
*			     作者:   阿甘
*		     开发时间:   2026/04/04
*			IDE 版 本:   Visual Studio 2026
*		     项目版本:   2.0.0.1
*---------------------------------------------------------------------------*/
//原文链接:https://ganzp1688.blog.csdn.net/?type=blog

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <map>
#include <memory>
#include <stdexcept>
#include <ctime>

using namespace std;

// ====================== 课程类 ======================
class Course {
private:
    string courseId;      // 课程编号
    string courseName;    // 课程名称
    int credit;           // 学分
    int hours;            // 学时
    
public:
    Course() : credit(0), hours(0) {}
    
    Course(const string& id, const string& name, int cred, int hr)
        : courseId(id), courseName(name), credit(cred), hours(hr) {}
    
    // Getter方法
    string getCourseId() const { return courseId; }
    string getCourseName() const { return courseName; }
    int getCredit() const { return credit; }
    int getHours() const { return hours; }
    
    // Setter方法
    void setCourseName(const string& name) { courseName = name; }
    void setCredit(int cred) { credit = cred; }
    void setHours(int hr) { hours = hr; }
    
    void display() const {
        cout << left << setw(12) << courseId
             << setw(20) << courseName
             << setw(8) << credit
             << setw(8) << hours << endl;
    }
    
    // 序列化
    string serialize() const {
        return courseId + "|" + courseName + "|" + 
               to_string(credit) + "|" + to_string(hours);
    }
    
    // 反序列化
    static Course deserialize(const string& data) {
        stringstream ss(data);
        string id, name, creditStr, hoursStr;
        getline(ss, id, '|');
        getline(ss, name, '|');
        getline(ss, creditStr, '|');
        getline(ss, hoursStr, '|');
        return Course(id, name, stoi(creditStr), stoi(hoursStr));
    }
};

// ====================== 成绩类 ======================
class Score {
private:
    string courseId;
    double score;
    string examTime;      // 考试时间
    string grade;         // 等级(优/良/中/及格/不及格)
    
    void calculateGrade() {
        if (score >= 90) grade = "优秀";
        else if (score >= 80) grade = "良好";
        else if (score >= 70) grade = "中等";
        else if (score >= 60) grade = "及格";
        else grade = "不及格";
    }
    
public:
    Score() : score(0.0) {}
    
    Score(const string& cid, double s, const string& time = "")
        : courseId(cid), score(s), examTime(time) {
        calculateGrade();
    }
    
    string getCourseId() const { return courseId; }
    double getScore() const { return score; }
    string getGrade() const { return grade; }
    string getExamTime() const { return examTime; }
    
    void setScore(double s) { 
        score = s; 
        calculateGrade();
    }
    
    void display() const {
        cout << left << setw(12) << courseId
             << setw(10) << fixed << setprecision(1) << score
             << setw(10) << grade
             << setw(20) << examTime << endl;
    }
    
    string serialize() const {
        return courseId + "|" + to_string(score) + "|" + examTime;
    }
    
    static Score deserialize(const string& data) {
        stringstream ss(data);
        string cid, scoreStr, time;
        getline(ss, cid, '|');
        getline(ss, scoreStr, '|');
        getline(ss, time, '|');
        return Score(cid, stod(scoreStr), time);
    }
};

// ====================== 学生类 ======================
class Student {
private:
    string stuId;           // 学号
    string name;            // 姓名
    string gender;          // 性别
    int age;                // 年龄
    string className;       // 班级
    string phone;           // 电话
    string email;           // 邮箱
    string address;         // 地址
    vector<Score> scores;   // 成绩列表
    static int totalStudents;
    
public:
    // 构造函数
    Student() : age(0) {}
    
    Student(const string& id, const string& n, const string& g, 
            int a, const string& cls, const string& p = "", 
            const string& em = "", const string& addr = "")
        : stuId(id), name(n), gender(g), age(a), className(cls),
          phone(p), email(em), address(addr) {
        totalStudents++;
    }
    
    // 拷贝构造
    Student(const Student& other)
        : stuId(other.stuId), name(other.name), gender(other.gender),
          age(other.age), className(other.className), phone(other.phone),
          email(other.email), address(other.address), scores(other.scores) {
        totalStudents++;
    }
    
    // 析构函数
    ~Student() {
        totalStudents--;
    }
    
    // 赋值运算符
    Student& operator=(const Student& other) {
        if (this != &other) {
            stuId = other.stuId;
            name = other.name;
            gender = other.gender;
            age = other.age;
            className = other.className;
            phone = other.phone;
            email = other.email;
            address = other.address;
            scores = other.scores;
        }
        return *this;
    }
    
    // ========== Getter方法 ==========
    string getStuId() const { return stuId; }
    string getName() const { return name; }
    string getGender() const { return gender; }
    int getAge() const { return age; }
    string getClassName() const { return className; }
    string getPhone() const { return phone; }
    string getEmail() const { return email; }
    string getAddress() const { return address; }
    const vector<Score>& getScores() const { return scores; }
    
    // ========== Setter方法 ==========
    void setName(const string& n) { name = n; }
    void setGender(const string& g) { gender = g; }
    void setAge(int a) { age = a; }
    void setClassName(const string& cls) { className = cls; }
    void setPhone(const string& p) { phone = p; }
    void setEmail(const string& em) { email = em; }
    void setAddress(const string& addr) { address = addr; }
    
    // ========== 成绩管理 ==========
    void addScore(const Score& score) {
        // 检查是否已有该课程成绩
        for (auto& s : scores) {
            if (s.getCourseId() == score.getCourseId()) {
                cout << "该课程成绩已存在,是否更新?(y/n): ";
                char ch;
                cin >> ch;
                if (ch == 'y' || ch == 'Y') {
                    s = score;
                    cout << "成绩已更新" << endl;
                }
                return;
            }
        }
        scores.push_back(score);
        cout << "成绩添加成功" << endl;
    }
    
    bool removeScore(const string& courseId) {
        auto it = find_if(scores.begin(), scores.end(),
            [&courseId](const Score& s) { return s.getCourseId() == courseId; });
        
        if (it != scores.end()) {
            scores.erase(it);
            cout << "成绩已删除" << endl;
            return true;
        }
        cout << "未找到该课程成绩" << endl;
        return false;
    }
    
    double getAverageScore() const {
        if (scores.empty()) return 0.0;
        double sum = 0.0;
        for (const auto& s : scores) {
            sum += s.getScore();
        }
        return sum / scores.size();
    }
    
    double getTotalScore() const {
        double sum = 0.0;
        for (const auto& s : scores) {
            sum += s.getScore();
        }
        return sum;
    }
    
    int getCourseCount() const {
        return scores.size();
    }
    
    // 获取最高分
    double getMaxScore() const {
        if (scores.empty()) return 0.0;
        double maxScore = scores[0].getScore();
        for (const auto& s : scores) {
            if (s.getScore() > maxScore) {
                maxScore = s.getScore();
            }
        }
        return maxScore;
    }
    
    // 获取最低分
    double getMinScore() const {
        if (scores.empty()) return 0.0;
        double minScore = scores[0].getScore();
        for (const auto& s : scores) {
            if (s.getScore() < minScore) {
                minScore = s.getScore();
            }
        }
        return minScore;
    }
    
    // 显示学生基本信息
    void displayBasic() const {
        cout << left << setw(12) << stuId
             << setw(12) << name
             << setw(6) << gender
             << setw(6) << age
             << setw(15) << className
             << setw(15) << phone
             << setw(25) << email << endl;
    }
    
    // 显示学生详细信息
    void displayDetail() const {
        cout << "\n================== 学生详细信息 ==================" << endl;
        cout << "学号: " << stuId << endl;
        cout << "姓名: " << name << endl;
        cout << "性别: " << gender << endl;
        cout << "年龄: " << age << endl;
        cout << "班级: " << className << endl;
        cout << "电话: " << (phone.empty() ? "未填写" : phone) << endl;
        cout << "邮箱: " << (email.empty() ? "未填写" : email) << endl;
        cout << "地址: " << (address.empty() ? "未填写" : address) << endl;
        cout << "================== 成绩信息 ==================" << endl;
        
        if (scores.empty()) {
            cout << "暂无成绩记录" << endl;
        } else {
            cout << left << setw(12) << "课程编号"
                 << setw(10) << "分数"
                 << setw(10) << "等级"
                 << setw(20) << "考试时间" << endl;
            cout << string(52, '-') << endl;
            for (const auto& s : scores) {
                s.display();
            }
            cout << string(52, '-') << endl;
            cout << "平均分: " << fixed << setprecision(2) << getAverageScore() << endl;
            cout << "总分: " << getTotalScore() << endl;
            cout << "最高分: " << getMaxScore() << endl;
            cout << "最低分: " << getMinScore() << endl;
            cout << "修读课程数: " << getCourseCount() << endl;
        }
        cout << "==================================================" << endl;
    }
    
    // 成绩表显示
    void displayScoreTable() const {
        cout << name << "(" << stuId << ") 成绩单:" << endl;
        cout << left << setw(20) << "课程名称"
             << setw(10) << "分数"
             << setw(10) << "等级" << endl;
        cout << string(40, '-') << endl;
        // 实际使用时需要关联课程名称,这里简化
        for (const auto& s : scores) {
            cout << left << setw(20) << s.getCourseId()
                 << setw(10) << fixed << setprecision(1) << s.getScore()
                 << setw(10) << s.getGrade() << endl;
        }
    }
    
    // 获取成绩等级描述
    string getGradeLevel() const {
        double avg = getAverageScore();
        if (avg >= 90) return "优秀";
        else if (avg >= 80) return "良好";
        else if (avg >= 70) return "中等";
        else if (avg >= 60) return "及格";
        else return "不及格";
    }
    
    // 比较运算符(用于排序)
    bool operator<(const Student& other) const {
        return getAverageScore() < other.getAverageScore();
    }
    
    bool operator>(const Student& other) const {
        return getAverageScore() > other.getAverageScore();
    }
    
    bool operator==(const Student& other) const {
        return stuId == other.stuId;
    }
    
    // 序列化
    string serialize() const {
        stringstream ss;
        ss << stuId << "|" << name << "|" << gender << "|" << age << "|"
           << className << "|" << phone << "|" << email << "|" << address << "|";
        
        // 序列化成绩
        ss << scores.size() << "|";
        for (const auto& score : scores) {
            ss << score.serialize() << "|";
        }
        return ss.str();
    }
    
    // 反序列化
    static Student deserialize(const string& data) {
        stringstream ss(data);
        string id, name, gender, ageStr, className, phone, email, address;
        string scoreCountStr;
        
        getline(ss, id, '|');
        getline(ss, name, '|');
        getline(ss, gender, '|');
        getline(ss, ageStr, '|');
        getline(ss, className, '|');
        getline(ss, phone, '|');
        getline(ss, email, '|');
        getline(ss, address, '|');
        getline(ss, scoreCountStr, '|');
        
        Student stu(id, name, gender, stoi(ageStr), className, phone, email, address);
        
        int scoreCount = stoi(scoreCountStr);
        for (int i = 0; i < scoreCount; i++) {
            string scoreData;
            getline(ss, scoreData, '|');
            if (!scoreData.empty()) {
                stu.scores.push_back(Score::deserialize(scoreData));
            }
        }
        
        return stu;
    }
    
    static int getTotalStudents() { return totalStudents; }
    static void resetTotalStudents() { totalStudents = 0; }
};

int Student::totalStudents = 0;

// ====================== 课程管理类 ======================
class CourseManager {
private:
    vector<Course> courses;
    static CourseManager* instance;
    string dataFile;
    
    CourseManager() : dataFile("courses.dat") {
        loadFromFile();
    }
    
public:
    static CourseManager& getInstance() {
        if (instance == nullptr) {
            instance = new CourseManager();
        }
        return *instance;
    }
    
    static void cleanup() {
        delete instance;
        instance = nullptr;
    }
    
    // 添加课程
    bool addCourse(const Course& course) {
        if (findCourse(course.getCourseId()) != -1) {
            cout << "课程编号已存在!" << endl;
            return false;
        }
        courses.push_back(course);
        saveToFile();
        cout << "课程添加成功" << endl;
        return true;
    }
    
    // 查找课程索引
    int findCourse(const string& courseId) const {
        for (size_t i = 0; i < courses.size(); i++) {
            if (courses[i].getCourseId() == courseId) {
                return i;
            }
        }
        return -1;
    }
    
    // 获取课程
    Course* getCourse(const string& courseId) {
        int idx = findCourse(courseId);
        if (idx != -1) {
            return &courses[idx];
        }
        return nullptr;
    }
    
    const Course* getCourse(const string& courseId) const {
        int idx = findCourse(courseId);
        if (idx != -1) {
            return &courses[idx];
        }
        return nullptr;
    }
    
    // 更新课程
    bool updateCourse(const string& courseId, const Course& newCourse) {
        int idx = findCourse(courseId);
        if (idx == -1) {
            cout << "课程不存在!" << endl;
            return false;
        }
        courses[idx] = newCourse;
        saveToFile();
        cout << "课程信息已更新" << endl;
        return true;
    }
    
    // 删除课程
    bool removeCourse(const string& courseId) {
        int idx = findCourse(courseId);
        if (idx == -1) {
            cout << "课程不存在!" << endl;
            return false;
        }
        courses.erase(courses.begin() + idx);
        saveToFile();
        cout << "课程已删除" << endl;
        return true;
    }
    
    // 显示所有课程
    void displayAllCourses() const {
        if (courses.empty()) {
            cout << "暂无课程信息" << endl;
            return;
        }
        cout << "\n================== 课程列表 ==================" << endl;
        cout << left << setw(12) << "课程编号"
             << setw(20) << "课程名称"
             << setw(8) << "学分"
             << setw(8) << "学时" << endl;
        cout << string(48, '-') << endl;
        for (const auto& course : courses) {
            course.display();
        }
        cout << "==============================================" << endl;
    }
    
    // 搜索课程
    void searchCourse(const string& keyword) const {
        bool found = false;
        cout << "\n================== 搜索结果 ==================" << endl;
        cout << left << setw(12) << "课程编号"
             << setw(20) << "课程名称"
             << setw(8) << "学分"
             << setw(8) << "学时" << endl;
        cout << string(48, '-') << endl;
        
        for (const auto& course : courses) {
            if (course.getCourseId().find(keyword) != string::npos ||
                course.getCourseName().find(keyword) != string::npos) {
                course.display();
                found = true;
            }
        }
        
        if (!found) {
            cout << "未找到相关课程" << endl;
        }
    }
    
    // 文件操作
    void saveToFile() const {
        ofstream file(dataFile);
        if (!file.is_open()) {
            cout << "无法打开文件保存课程数据" << endl;
            return;
        }
        
        for (const auto& course : courses) {
            file << course.serialize() << endl;
        }
        file.close();
    }
    
    void loadFromFile() {
        courses.clear();
        ifstream file(dataFile);
        if (!file.is_open()) {
            return;
        }
        
        string line;
        while (getline(file, line)) {
            if (!line.empty()) {
                courses.push_back(Course::deserialize(line));
            }
        }
        file.close();
    }
    
    size_t getCourseCount() const { return courses.size(); }
};

CourseManager* CourseManager::instance = nullptr;

// ====================== 学生管理类 ======================
class StudentManager {
private:
    vector<Student> students;
    string dataFile;
    
public:
    StudentManager() : dataFile("students.dat") {
        loadFromFile();
    }
    
    ~StudentManager() {
        saveToFile();
    }
    
    // ========== 增删改查 ==========
    
    // 添加学生
    bool addStudent(const Student& student) {
        if (findStudent(student.getStuId()) != -1) {
            cout << "学号已存在!" << endl;
            return false;
        }
        students.push_back(student);
        saveToFile();
        cout << "学生添加成功" << endl;
        return true;
    }
    
    // 查找学生索引
    int findStudent(const string& stuId) const {
        for (size_t i = 0; i < students.size(); i++) {
            if (students[i].getStuId() == stuId) {
                return i;
            }
        }
        return -1;
    }
    
    // 获取学生
    Student* getStudent(const string& stuId) {
        int idx = findStudent(stuId);
        if (idx != -1) {
            return &students[idx];
        }
        return nullptr;
    }
    
    // 更新学生信息
    bool updateStudent(const string& stuId, const Student& newStudent) {
        int idx = findStudent(stuId);
        if (idx == -1) {
            cout << "学生不存在!" << endl;
            return false;
        }
        students[idx] = newStudent;
        saveToFile();
        cout << "学生信息已更新" << endl;
        return true;
    }
    
    // 删除学生
    bool removeStudent(const string& stuId) {
        int idx = findStudent(stuId);
        if (idx == -1) {
            cout << "学生不存在!" << endl;
            return false;
        }
        students.erase(students.begin() + idx);
        saveToFile();
        cout << "学生已删除" << endl;
        return true;
    }
    
    // ========== 成绩管理 ==========
    
    // 添加成绩
    bool addScore(const string& stuId, const Score& score) {
        int idx = findStudent(stuId);
        if (idx == -1) {
            cout << "学生不存在!" << endl;
            return false;
        }
        
        // 验证课程是否存在
        if (CourseManager::getInstance().getCourse(score.getCourseId()) == nullptr) {
            cout << "课程不存在!请先添加课程" << endl;
            return false;
        }
        
        students[idx].addScore(score);
        saveToFile();
        return true;
    }
    
    // 删除成绩
    bool removeScore(const string& stuId, const string& courseId) {
        int idx = findStudent(stuId);
        if (idx == -1) {
            cout << "学生不存在!" << endl;
            return false;
        }
        bool result = students[idx].removeScore(courseId);
        if (result) {
            saveToFile();
        }
        return result;
    }
    
    // ========== 查询显示 ==========
    
    // 显示所有学生(简要信息)
    void displayAllStudents() const {
        if (students.empty()) {
            cout << "暂无学生信息" << endl;
            return;
        }
        cout << "\n================== 学生列表 ==================" << endl;
        cout << left << setw(12) << "学号"
             << setw(12) << "姓名"
             << setw(6) << "性别"
             << setw(6) << "年龄"
             << setw(15) << "班级"
             << setw(15) << "电话"
             << setw(25) << "邮箱" << endl;
        cout << string(91, '-') << endl;
        for (const auto& student : students) {
            student.displayBasic();
        }
        cout << "================================================" << endl;
        cout << "总人数: " << students.size() << endl;
    }
    
    // 显示学生详细信息
    void displayStudentDetail(const string& stuId) const {
        int idx = findStudent(stuId);
        if (idx == -1) {
            cout << "学生不存在!" << endl;
            return;
        }
        students[idx].displayDetail();
    }
    
    // 按班级显示学生
    void displayByClass(const string& className) const {
        bool found = false;
        cout << "\n================== " << className << " 班学生列表 ==================" << endl;
        cout << left << setw(12) << "学号"
             << setw(12) << "姓名"
             << setw(6) << "性别"
             << setw(6) << "年龄"
             << setw(10) << "平均分"
             << setw(8) << "等级" << endl;
        cout << string(54, '-') << endl;
        
        for (const auto& student : students) {
            if (student.getClassName() == className) {
                cout << left << setw(12) << student.getStuId()
                     << setw(12) << student.getName()
                     << setw(6) << student.getGender()
                     << setw(6) << student.getAge()
                     << setw(10) << fixed << setprecision(1) << student.getAverageScore()
                     << setw(8) << student.getGradeLevel() << endl;
                found = true;
            }
        }
        
        if (!found) {
            cout << "该班级暂无学生" << endl;
        }
    }
    
    // 搜索学生
    void searchStudent(const string& keyword) const {
        bool found = false;
        cout << "\n================== 搜索结果 ==================" << endl;
        cout << left << setw(12) << "学号"
             << setw(12) << "姓名"
             << setw(6) << "性别"
             << setw(6) << "年龄"
             << setw(15) << "班级"
             << setw(10) << "平均分" << endl;
        cout << string(61, '-') << endl;
        
        for (const auto& student : students) {
            if (student.getStuId().find(keyword) != string::npos ||
                student.getName().find(keyword) != string::npos) {
                cout << left << setw(12) << student.getStuId()
                     << setw(12) << student.getName()
                     << setw(6) << student.getGender()
                     << setw(6) << student.getAge()
                     << setw(15) << student.getClassName()
                     << setw(10) << fixed << setprecision(1) << student.getAverageScore() << endl;
                found = true;
            }
        }
        
        if (!found) {
            cout << "未找到相关学生" << endl;
        }
    }
    
    // ========== 排序功能 ==========
    
    // 按学号排序
    void sortByStuId() {
        sort(students.begin(), students.end(),
            [](const Student& a, const Student& b) {
                return a.getStuId() < b.getStuId();
            });
        cout << "已按学号排序" << endl;
    }
    
    // 按姓名排序
    void sortByName() {
        sort(students.begin(), students.end(),
            [](const Student& a, const Student& b) {
                return a.getName() < b.getName();
            });
        cout << "已按姓名排序" << endl;
    }
    
    // 按平均分排序
    void sortByAverage(bool descending = true) {
        if (descending) {
            sort(students.begin(), students.end(),
                [](const Student& a, const Student& b) {
                    return a.getAverageScore() > b.getAverageScore();
                });
            cout << "已按平均分降序排序" << endl;
        } else {
            sort(students.begin(), students.end(),
                [](const Student& a, const Student& b) {
                    return a.getAverageScore() < b.getAverageScore();
                });
            cout << "已按平均分升序排序" << endl;
        }
    }
    
    // ========== 统计分析 ==========
    
    // 成绩统计分析
    void gradeStatistics() const {
        if (students.empty()) {
            cout << "暂无学生数据" << endl;
            return;
        }
        
        map<string, int> gradeDistribution;
        double totalAvg = 0.0;
        int studentCount = 0;
        
        for (const auto& student : students) {
            if (student.getCourseCount() > 0) {
                totalAvg += student.getAverageScore();
                studentCount++;
                gradeDistribution[student.getGradeLevel()]++;
            }
        }
        
        cout << "\n================== 成绩统计分析 ==================" << endl;
        cout << "参与统计学生数: " << studentCount << endl;
        cout << "全校平均分: " << fixed << setprecision(2) 
             << (studentCount > 0 ? totalAvg / studentCount : 0) << endl;
        cout << "\n等级分布:" << endl;
        cout << left << setw(10) << "等级" << setw(10) << "人数" << setw(10) << "占比" << endl;
        cout << string(30, '-') << endl;
        
        for (const auto& pair : gradeDistribution) {
            double percent = (double)pair.second / studentCount * 100;
            cout << left << setw(10) << pair.first
                 << setw(10) << pair.second
                 << setw(10) << fixed << setprecision(1) << percent << "%" << endl;
        }
        cout << "==================================================" << endl;
    }
    
    // 班级排名
    void classRanking(const string& className) const {
        vector<pair<string, double>> classScores;
        
        for (const auto& student : students) {
            if (student.getClassName() == className && student.getCourseCount() > 0) {
                classScores.push_back({student.getName(), student.getAverageScore()});
            }
        }
        
        if (classScores.empty()) {
            cout << "该班级暂无成绩数据" << endl;
            return;
        }
        
        sort(classScores.begin(), classScores.end(),
            [](const pair<string, double>& a, const pair<string, double>& b) {
                return a.second > b.second;
            });
        
        cout << "\n================== " << className << " 班成绩排名 ==================" << endl;
        cout << left << setw(8) << "名次"
             << setw(12) << "姓名"
             << setw(10) << "平均分" << endl;
        cout << string(30, '-') << endl;
        
        for (size_t i = 0; i < classScores.size(); i++) {
            cout << left << setw(8) << (i + 1)
                 << setw(12) << classScores[i].first
                 << setw(10) << fixed << setprecision(1) << classScores[i].second << endl;
        }
    }
    
    // ========== 文件操作 ==========
    
    void saveToFile() const {
        ofstream file(dataFile);
        if (!file.is_open()) {
            cout << "无法打开文件保存学生数据" << endl;
            return;
        }
        
        for (const auto& student : students) {
            file << student.serialize() << endl;
        }
        file.close();
    }
    
    void loadFromFile() {
        students.clear();
        Student::resetTotalStudents();
        
        ifstream file(dataFile);
        if (!file.is_open()) {
            return;
        }
        
        string line;
        while (getline(file, line)) {
            if (!line.empty()) {
                students.push_back(Student::deserialize(line));
            }
        }
        file.close();
    }
    
    size_t getStudentCount() const { return students.size(); }
    
    // 获取所有班级列表
    vector<string> getAllClasses() const {
        vector<string> classes;
        for (const auto& student : students) {
            string className = student.getClassName();
            if (find(classes.begin(), classes.end(), className) == classes.end()) {
                classes.push_back(className);
            }
        }
        return classes;
    }
};

// ====================== 菜单系统 ======================
class MenuSystem {
private:
    StudentManager studentManager;
    CourseManager& courseManager;
    
    void clearScreen() {
#ifdef _WIN32
        system("cls");
#else
        system("clear");
#endif
    }
    
    void pause() {
        cout << "\n按回车键继续...";
        cin.ignore();
        cin.get();
    }
    
    void showMainMenu() {
        cout << "\n";
        cout << "╔══════════════════════════════════════════════════════════╗\n";
        cout << "║                 学生信息管理系统                        ║\n";
        cout = "╠══════════════════════════════════════════════════════════╣\n";
        cout << "║  1. 学生管理                                            ║\n";
        cout << "║  2. 课程管理                                            ║\n";
        cout << "║  3. 成绩管理                                            ║\n";
        cout << "║  4. 查询统计                                            ║\n";
        cout << "║  5. 数据排序                                            ║\n";
        cout << "║  0. 退出系统                                            ║\n";
        cout << "╚══════════════════════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
    void showStudentMenu() {
        cout << "\n";
        cout << "╔════════════════════════════════════════╗\n";
        cout << "║           学生管理子菜单               ║\n";
        cout << "╠════════════════════════════════════════╣\n";
        cout << "║  1. 添加学生                          ║\n";
        cout << "║  2. 修改学生信息                      ║\n";
        cout << "║  3. 删除学生                          ║\n";
        cout << "║  4. 查看所有学生                      ║\n";
        cout << "║  5. 查看学生详细信息                  ║\n";
        cout << "║  6. 按班级查看学生                    ║\n";
        cout << "║  0. 返回主菜单                        ║\n";
        cout << "╚════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
    void showCourseMenu() {
        cout << "\n";
        cout << "╔════════════════════════════════════════╗\n";
        cout << "║           课程管理子菜单               ║\n";
        cout << "╠════════════════════════════════════════╣\n";
        cout << "║  1. 添加课程                          ║\n";
        cout << "║  2. 修改课程信息                      ║\n";
        cout << "║  3. 删除课程                          ║\n";
        cout << "║  4. 查看所有课程                      ║\n";
        cout << "║  5. 搜索课程                          ║\n";
        cout << "║  0. 返回主菜单                        ║\n";
        cout << "╚════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
    void showScoreMenu() {
        cout << "\n";
        cout << "╔════════════════════════════════════════╗\n";
        cout << "║           成绩管理子菜单               ║\n";
        cout << "╠════════════════════════════════════════╣\n";
        cout << "║  1. 添加/修改成绩                     ║\n";
        cout << "║  2. 删除成绩                          ║\n";
        cout << "║  3. 查看学生成绩单                    ║\n";
        cout << "║  0. 返回主菜单                        ║\n";
        cout << "╚════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
    void showQueryMenu() {
        cout << "\n";
        cout << "╔════════════════════════════════════════╗\n";
        cout << "║           查询统计子菜单               ║\n";
        cout << "╠════════════════════════════════════════╣\n";
        cout << "║  1. 搜索学生(学号/姓名)             ║\n";
        cout << "║  2. 成绩统计分析                      ║\n";
        cout << "║  3. 班级成绩排名                      ║\n";
        cout << "║  0. 返回主菜单                        ║\n";
        cout << "╚════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
    void showSortMenu() {
        cout << "\n";
        cout << "╔════════════════════════════════════════╗\n";
        cout << "║           排序子菜单                   ║\n";
        cout << "╠════════════════════════════════════════╣\n";
        cout << "║  1. 按学号排序                        ║\n";
        cout << "║  2. 按姓名排序                        ║\n";
        cout << "║  3. 按平均分降序排序                  ║\n";
        cout << "║  4. 按平均分升序排序                  ║\n";
        cout << "║  0. 返回主菜单                        ║\n";
        cout << "╚════════════════════════════════════════╝\n";
        cout << "请选择操作: ";
    }
    
public:
    MenuSystem() : courseManager(CourseManager::getInstance()) {}
    
    void run() {
        int choice;
        do {
            showMainMenu();
            cin >> choice;
            
            switch (choice) {
                case 1:
                    studentManagement();
                    break;
                case 2:
                    courseManagement();
                    break;
                case 3:
                    scoreManagement();
                    break;
                case 4:
                    queryAndStatistic();
                    break;
                case 5:
                    sortManagement();
                    break;
                case 0:
                    cout << "感谢使用学生信息管理系统,再见!" << endl;
                    break;
                default:
                    cout << "无效选择,请重新输入!" << endl;
                    pause();
            }
        } while (choice != 0);
    }
    
    void studentManagement() {
        int choice;
        do {
            showStudentMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: {
                    string id, name, gender, className, phone, email, address;
                    int age;
                    
                    cout << "请输入学号: ";
                    cin >> id;
                    cout << "请输入姓名: ";
                    cin >> name;
                    cout << "请输入性别(男/女): ";
                    cin >> gender;
                    cout << "请输入年龄: ";
                    cin >> age;
                    cout << "请输入班级: ";
                    cin >> className;
                    cout << "请输入电话: ";
                    cin >> phone;
                    cout << "请输入邮箱: ";
                    cin >> email;
                    cout << "请输入地址: ";
                    cin.ignore();
                    getline(cin, address);
                    
                    Student stu(id, name, gender, age, className, phone, email, address);
                    studentManager.addStudent(stu);
                    pause();
                    break;
                }
                case 2: {
                    string id;
                    cout << "请输入要修改的学生学号: ";
                    cin >> id;
                    
                    Student* stu = studentManager.getStudent(id);
                    if (stu) {
                        string name, gender, className, phone, email, address;
                        int age;
                        
                        cout << "当前信息 - 姓名: " << stu->getName() << endl;
                        cout << "请输入新姓名(直接回车保留原值): ";
                        cin.ignore();
                        getline(cin, name);
                        if (!name.empty()) stu->setName(name);
                        
                        cout << "当前性别: " << stu->getGender() << endl;
                        cout << "请输入新性别: ";
                        getline(cin, gender);
                        if (!gender.empty()) stu->setGender(gender);
                        
                        cout << "当前年龄: " << stu->getAge() << endl;
                        cout << "请输入新年龄: ";
                        string ageStr;
                        getline(cin, ageStr);
                        if (!ageStr.empty()) stu->setAge(stoi(ageStr));
                        
                        cout << "当前班级: " << stu->getClassName() << endl;
                        cout << "请输入新班级: ";
                        getline(cin, className);
                        if (!className.empty()) stu->setClassName(className);
                        
                        cout << "当前电话: " << stu->getPhone() << endl;
                        cout << "请输入新电话: ";
                        getline(cin, phone);
                        if (!phone.empty()) stu->setPhone(phone);
                        
                        cout << "当前邮箱: " << stu->getEmail() << endl;
                        cout << "请输入新邮箱: ";
                        getline(cin, email);
                        if (!email.empty()) stu->setEmail(email);
                        
                        cout << "当前地址: " << stu->getAddress() << endl;
                        cout << "请输入新地址: ";
                        getline(cin, address);
                        if (!address.empty()) stu->setAddress(address);
                        
                        studentManager.updateStudent(id, *stu);
                    } else {
                        cout << "学生不存在!" << endl;
                    }
                    pause();
                    break;
                }
                case 3: {
                    string id;
                    cout << "请输入要删除的学生学号: ";
                    cin >> id;
                    studentManager.removeStudent(id);
                    pause();
                    break;
                }
                case 4:
                    studentManager.displayAllStudents();
                    pause();
                    break;
                case 5: {
                    string id;
                    cout << "请输入学生学号: ";
                    cin >> id;
                    studentManager.displayStudentDetail(id);
                    pause();
                    break;
                }
                case 6: {
                    string className;
                    cout << "请输入班级名称: ";
                    cin >> className;
                    studentManager.displayByClass(className);
                    pause();
                    break;
                }
            }
        } while (choice != 0);
    }
    
    void courseManagement() {
        int choice;
        do {
            showCourseMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: {
                    string id, name;
                    int credit, hours;
                    
                    cout << "请输入课程编号: ";
                    cin >> id;
                    cout << "请输入课程名称: ";
                    cin >> name;
                    cout << "请输入学分: ";
                    cin >> credit;
                    cout << "请输入学时: ";
                    cin >> hours;
                    
                    Course course(id, name, credit, hours);
                    courseManager.addCourse(course);
                    pause();
                    break;
                }
                case 2: {
                    string id;
                    cout << "请输入要修改的课程编号: ";
                    cin >> id;
                    
                    Course* course = courseManager.getCourse(id);
                    if (course) {
                        string name;
                        int credit, hours;
                        
                        cout << "当前课程名: " << course->getCourseName() << endl;
                        cout << "请输入新课程名: ";
                        cin >> name;
                        if (!name.empty()) course->setCourseName(name);
                        
                        cout << "当前学分: " << course->getCredit() << endl;
                        cout << "请输入新学分: ";
                        string creditStr;
                        cin >> creditStr;
                        if (!creditStr.empty()) course->setCredit(stoi(creditStr));
                        
                        cout << "当前学时: " << course->getHours() << endl;
                        cout << "请输入新学时: ";
                        string hoursStr;
                        cin >> hoursStr;
                        if (!hoursStr.empty()) course->setHours(stoi(hoursStr));
                        
                        courseManager.updateCourse(id, *course);
                    } else {
                        cout << "课程不存在!" << endl;
                    }
                    pause();
                    break;
                }
                case 3: {
                    string id;
                    cout << "请输入要删除的课程编号: ";
                    cin >> id;
                    courseManager.removeCourse(id);
                    pause();
                    break;
                }
                case 4:
                    courseManager.displayAllCourses();
                    pause();
                    break;
                case 5: {
                    string keyword;
                    cout << "请输入搜索关键词: ";
                    cin >> keyword;
                    courseManager.searchCourse(keyword);
                    pause();
                    break;
                }
            }
        } while (choice != 0);
    }
    
    void scoreManagement() {
        int choice;
        do {
            showScoreMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: {
                    string stuId, courseId, examTime;
                    double score;
                    
                    cout << "请输入学生学号: ";
                    cin >> stuId;
                    cout << "请输入课程编号: ";
                    cin >> courseId;
                    cout << "请输入成绩: ";
                    cin >> score;
                    cout << "请输入考试时间(格式: YYYY-MM-DD): ";
                    cin >> examTime;
                    
                    Score sc(courseId, score, examTime);
                    studentManager.addScore(stuId, sc);
                    pause();
                    break;
                }
                case 2: {
                    string stuId, courseId;
                    cout << "请输入学生学号: ";
                    cin >> stuId;
                    cout << "请输入课程编号: ";
                    cin >> courseId;
                    studentManager.removeScore(stuId, courseId);
                    pause();
                    break;
                }
                case 3: {
                    string stuId;
                    cout << "请输入学生学号: ";
                    cin >> stuId;
                    studentManager.displayStudentDetail(stuId);
                    pause();
                    break;
                }
            }
        } while (choice != 0);
    }
    
    void queryAndStatistic() {
        int choice;
        do {
            showQueryMenu();
            cin >> choice;
            
            switch (choice) {
                case 1: {
                    string keyword;
                    cout << "请输入搜索关键词(学号/姓名): ";
                    cin >> keyword;
                    studentManager.searchStudent(keyword);
                    pause();
                    break;
                }
                case 2:
                    studentManager.gradeStatistics();
                    pause();
                    break;
                case 3: {
                    string className;
                    cout << "请输入班级名称: ";
                    cin >> className;
                    studentManager.classRanking(className);
                    pause();
                    break;
                }
            }
        } while (choice != 0);
    }
    
    void sortManagement() {
        int choice;
        do {
            showSortMenu();
            cin >> choice;
            
            switch (choice) {
                case 1:
                    studentManager.sortByStuId();
                    studentManager.displayAllStudents();
                    pause();
                    break;
                case 2:
                    studentManager.sortByName();
                    studentManager.displayAllStudents();
                    pause();
                    break;
                case 3:
                    studentManager.sortByAverage(true);
                    studentManager.displayAllStudents();
                    pause();
                    break;
                case 4:
                    studentManager.sortByAverage(false);
                    studentManager.displayAllStudents();
                    pause();
                    break;
            }
        } while (choice != 0);
    }
};

// ====================== 主函数 ======================
int main() {
    cout << "╔══════════════════════════════════════════════════════════════╗\n";
    cout << "║                                                              ║\n";
    cout << "║             欢迎使用学生信息管理系统 V2.0                      ║\n";
    cout << "║                                                              ║\n";
    cout << "║                    瑶池酒剑仙 出品                            ║\n";
    cout << "║                                                              ║\n";
    cout << "╚══════════════════════════════════════════════════════════════╝\n";
    
    MenuSystem menu;
    menu.run();
    
    CourseManager::cleanup();
    
    return 0;
}

大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!

🌲 请进入下一专栏: 项目实战合集

🌲 彩蛋壁纸别忘了先看哈!


新壁纸(雨夜论道)


墨智:今日有无根水降,这洼地之水,便是生,他日无根水失,这洼地之水,便是死,没有了生机,没有了流通,所谓死水,便是如此!
今日,他们可喜、可怒、可哀、可乐,便是生,他日,他们不会喜怒哀乐,难逃轮回,便是死。
此庙宇神像在时,庙宇为生,如今神像消失,便是死!
这雨,出生于天,死于大地,中间的过程,便是人生,我之所以看这雨水,不看天,不看地,看的也不是雨,而是这雨的一生......这便是生与死!

相关推荐
三品吉他手会点灯1 小时前
C语言学习笔记 - 27.C编程预备计算机专业知识 - 什么是字节
c语言·开发语言·笔记·学习
许彰午1 小时前
政务远程帮办部署踩坑实录——从互联网到政务外网
开发语言·网络·政务
潇湘散客2 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl
Ricky_Theseus2 小时前
const 和 #define 的区别
c++
WBluuue2 小时前
Codeforces 1094 Div1+2(ABCDE)
c++·算法
存在的五月雨2 小时前
项目中 Vitest 配置详解:vitest.config.ts
开发语言·javascript·vue.js
野犬寒鸦3 小时前
Claude Code:终端AI编程助手全指南(附带指令全讲解)
开发语言·后端·面试·ai编程
淡笑沐白3 小时前
JavaScript零基础到精通
开发语言·javascript·ecmascript