编写模块化的的C++代码演示案例

基础演示案例1

当你在编写模块化的 C++ 代码时,目标是创建可重用、易于维护并且功能明确的组件。下面是一个简单的例子,展示如何将一个程序分解成几个模块。我们将创建一个简单的数学运算库,包括加法和乘法函数,并且使用一个主函数来演示这些功能。

首先,我们从定义一个头文件(header file)开始,这个头文件会包含我们的函数声明。

math_functions.h

#ifndef MATH_FUNCTIONS_H
#define MATH_FUNCTIONS_H

// 函数声明
double add(double x, double y);
double multiply(double x, double y);

#endif // MATH_FUNCTIONS_H

然后,我们需要创建一个源文件(source file),在这个文件中定义我们的函数。

math_functions.cpp

#include "math_functions.h"

// 函数定义
double add(double x, double y) {
    return x + y;
}

double multiply(double x, double y) {
    return x * y;
}

最后,我们需要一个主程序来测试这些函数。

main.cpp

#include <iostream>
#include "math_functions.h"

int main() {
    double result_add = add(5.0, 3.0);
    double result_multiply = multiply(5.0, 3.0);

    std::cout << "Addition: " << result_add << std::endl;
    std::cout << "Multiplication: " << result_multiply << std::endl;

    return 0;
}

为了编译这些文件,你可以使用命令行工具,假设你将所有的文件放在同一个目录下,并且使用 g++ 编译器:

g++ -c math_functions.cpp
g++ -o my_program main.cpp math_functions.o

第一条命令将 math_functions.cpp 编译为对象文件 math_functions.o。第二条命令则链接 main.cppmath_functions.o,并生成一个名为 my_program 的可执行文件。

以上就是构建一个简单模块化 C++ 应用程序的基本步骤。在实际开发中,你可能还需要考虑其他因素如错误处理、单元测试等。此外,对于较大的项目,可以使用构建系统(如 CMake 或 Makefiles)来自动化编译过程。

案例扩展

让我们继续扩展这个模块化的 C++ 代码示例,以包含更多的功能和结构上的改进。

扩展数学库

我们可以为数学库添加更多功能,并确保它保持良好的组织结构。例如,我们可以增加一些新的功能,如减法和除法函数。

math_functions.h (更新)
#ifndef MATH_FUNCTIONS_H
#define MATH_FUNCTIONS_H

// 函数声明
double add(double x, double y);
double subtract(double x, double y);
double multiply(double x, double y);
double divide(double x, double y);

#endif // MATH_FUNCTIONS_H
math_functions.cpp (更新)
#include "math_functions.h"

// 函数定义
double add(double x, double y) {
    return x + y;
}

double subtract(double x, double y) {
    return x - y;
}

double multiply(double x, double y) {
    return x * y;
}

double divide(double x, double y) {
    if (y == 0) {
        throw std::invalid_argument("Division by zero is not allowed.");
    }
    return x / y;
}

我们增加了两个新的函数 subtractdivide,同时在 divide 函数中添加了错误检查,以防止除数为零的情况。

更新主程序

现在我们可以更新 main.cpp 文件来测试所有新增的功能。

main.cpp (更新)
#include <iostream>
#include <stdexcept>
#include "math_functions.h"

int main() {
    try {
        double result_add = add(5.0, 3.0);
        double result_subtract = subtract(5.0, 3.0);
        double result_multiply = multiply(5.0, 3.0);
        double result_divide = divide(5.0, 3.0);

        std::cout << "Addition: " << result_add << std::endl;
        std::cout << "Subtraction: " << result_subtract << std::endl;
        std::cout << "Multiplication: " << result_multiply << std::endl;
        std::cout << "Division: " << result_divide << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

这里我们在 main 函数中使用了 try-catch 块来捕获任何由 divide 函数抛出的异常。

使用构建系统

对于较大的项目,手动管理依赖关系和编译步骤可能会变得复杂。我们可以使用 CMake 来帮助我们自动化构建流程。以下是如何设置一个简单的 CMakeLists.txt 文件。

CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MathLib VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)

add_executable(my_program main.cpp math_functions.cpp)

有了这个 CMake 配置文件后,你可以在终端中运行以下命令来配置和构建项目:

mkdir build
cd build
cmake ..
make

这将会在 build 目录下生成一个名为 my_program 的可执行文件。

通过这种方式,你可以继续扩展你的数学库,增加更多功能或优化现有功能,并保持代码的清晰和模块化。

演示案例2:学生信息管理系统

我们可以创建一个更加具体的案例,比如一个简单的学生信息管理系统。这个系统可以用来存储学生的个人信息以及他们的成绩,并提供基本的查询和修改功能。

设计模块

我们可以将这个系统分为以下几个模块:

  1. 数据模型:用于表示学生的信息和成绩。
  2. 数据访问层:用于管理学生数据的存储和检索。
  3. 业务逻辑层:实现对学生数据的操作,如添加、删除、更新和查询。
  4. 用户界面:用于与用户交互,接收输入并显示结果。

数据模型

首先,定义一个学生类来存储学生的相关信息。

student.h
#ifndef STUDENT_H
#define STUDENT_H

#include <string>

class Student {
public:
    Student(const std::string& name, int age, const std::string& id);
    ~Student();

    const std::string& getName() const { return name_; }
    int getAge() const { return age_; }
    const std::string& getId() const { return id_; }

private:
    std::string name_;
    int age_;
    std::string id_;
};

#endif // STUDENT_H
student.cpp
#include "student.h"
#include <iostream>

Student::Student(const std::string& name, int age, const std::string& id)
    : name_(name), age_(age), id_(id) {}

Student::~Student() {}

数据访问层

接下来,定义一个类来处理学生数据的存储。这里我们使用一个简单的向量来模拟数据库。

student_database.h
#ifndef STUDENT_DATABASE_H
#define STUDENT_DATABASE_H

#include <vector>
#include <memory>
#include "student.h"

class StudentDatabase {
public:
    void addStudent(const std::shared_ptr<Student>& student);
    void removeStudent(const std::string& id);
    std::shared_ptr<Student> findStudentById(const std::string& id);
    void updateStudent(const std::string& id, const std::shared_ptr<Student>& newStudent);
    std::vector<std::shared_ptr<Student>> getAllStudents();

private:
    std::vector<std::shared_ptr<Student>> students_;
};

#endif // STUDENT_DATABASE_H
student_database.cpp
#include "student_database.h"

void StudentDatabase::addStudent(const std::shared_ptr<Student>& student) {
    students_.push_back(student);
}

void StudentDatabase::removeStudent(const std::string& id) {
    students_.erase(std::remove_if(students_.begin(), students_.end(),
                                   [id](const std::shared_ptr<Student>& s) { return s->getId() == id; }),
                    students_.end());
}

std::shared_ptr<Student> StudentDatabase::findStudentById(const std::string& id) {
    for (auto& student : students_) {
        if (student->getId() == id) {
            return student;
        }
    }
    return nullptr;
}

void StudentDatabase::updateStudent(const std::string& id, const std::shared_ptr<Student>& newStudent) {
    auto it = std::find_if(students_.begin(), students_.end(),
                           [id](const std::shared_ptr<Student>& s) { return s->getId() == id; });
    if (it != students_.end()) {
        *it = newStudent;
    }
}

std::vector<std::shared_ptr<Student>> StudentDatabase::getAllStudents() {
    return students_;
}

用户界面

最后,我们创建一个简单的命令行界面来与用户交互。

main.cpp
#include <iostream>
#include <memory>
#include "student.h"
#include "student_database.h"

int main() {
    StudentDatabase db;

    while (true) {
        std::cout << "1. Add Student" << std::endl;
        std::cout << "2. Remove Student" << std::endl;
        std::cout << "3. Find Student" << std::endl;
        std::cout << "4. Update Student" << std::endl;
        std::cout << "5. List All Students" << std::endl;
        std::cout << "6. Exit" << std::endl;
        std::cout << "Enter your choice: ";
        int choice;
        std::cin >> choice;

        switch (choice) {
            case 1: {
                std::string name, id;
                int age;
                std::cout << "Enter name: ";
                std::cin >> name;
                std::cout << "Enter age: ";
                std::cin >> age;
                std::cout << "Enter ID: ";
                std::cin >> id;
                auto student = std::make_shared<Student>(name, age, id);
                db.addStudent(student);
                break;
            }
            case 2: {
                std::string id;
                std::cout << "Enter ID to remove: ";
                std::cin >> id;
                db.removeStudent(id);
                break;
            }
            case 3: {
                std::string id;
                std::cout << "Enter ID to find: ";
                std::cin >> id;
                auto student = db.findStudentById(id);
                if (student) {
                    std::cout << "Name: " << student->getName() << std::endl;
                    std::cout << "Age: " << student->getAge() << std::endl;
                    std::cout << "ID: " << student->getId() << std::endl;
                } else {
                    std::cout << "Student not found." << std::endl;
                }
                break;
            }
            case 4: {
                std::string id;
                std::cout << "Enter ID to update: ";
                std::cin >> id;
                auto student = db.findStudentById(id);
                if (student) {
                    std::string newName, newId;
                    int newAge;
                    std::cout << "Enter new name: ";
                    std::cin >> newName;
                    std::cout << "Enter new age: ";
                    std::cin >> newAge;
                    std::cout << "Enter new ID: ";
                    std::cin >> newId;
                    auto newStudent = std::make_shared<Student>(newName, newAge, newId);
                    db.updateStudent(id, newStudent);
                } else {
                    std::cout << "Student not found." << std::endl;
                }
                break;
            }
            case 5: {
                auto students = db.getAllStudents();
                for (auto& student : students) {
                    std::cout << "Name: " << student->getName() << std::endl;
                    std::cout << "Age: " << student->getAge() << std::endl;
                    std::cout << "ID: " << student->getId() << std::endl;
                    std::cout << "-----------------" << std::endl;
                }
                break;
            }
            case 6: {
                return 0;
            }
            default:
                std::cout << "Invalid choice. Please try again." << std::endl;
        }
    }

    return 0;
}

编译和运行

使用 CMake 构建这个项目,可以在 CMakeLists.txt 中添加如下内容:

CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(StudentInfoSystem VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)

add_executable(student_info_system main.cpp student.cpp student_database.cpp)
target_include_directories(student_info_system PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

然后,在终端中运行以下命令:

mkdir build
cd build
cmake ..
make
./student_info_system

这样就建立了一个简单的学生信息管理系统,可以用来管理和查询学生的相关信息。你可以根据需要进一步扩展这个系统的功能,比如增加成绩管理、持久化存储等功能。

案例扩展

让我们继续扩展这个学生信息管理系统,使其更加强大和实用。我们将添加成绩管理和持久化存储的功能。

成绩管理

我们将为每个学生添加一个成绩记录的功能,可以通过添加新的类来管理成绩,并在学生类中添加对成绩的引用。

grade.h
#ifndef GRADE_H
#define GRADE_H

#include <string>

class Grade {
public:
    Grade(const std::string& subject, double score);
    ~Grade();

    const std::string& getSubject() const { return subject_; }
    double getScore() const { return score_; }

private:
    std::string subject_;
    double score_;
};

#endif // GRADE_H
grade.cpp
#include "grade.h"

Grade::Grade(const std::string& subject, double score)
    : subject_(subject), score_(score) {}

Grade::~Grade() {}
student.h (更新)
#ifndef STUDENT_H
#define STUDENT_H

#include <string>
#include <vector>
#include <memory>
#include "grade.h"

class Student {
public:
    Student(const std::string& name, int age, const std::string& id);
    ~Student();

    const std::string& getName() const { return name_; }
    int getAge() const { return age_; }
    const std::string& getId() const { return id_; }

    void addGrade(const std::shared_ptr<Grade>& grade);
    std::vector<std::shared_ptr<Grade>> getGrades() const;

private:
    std::string name_;
    int age_;
    std::string id_;
    std::vector<std::shared_ptr<Grade>> grades_;
};

#endif // STUDENT_H
student.cpp (更新)
#include "student.h"

Student::Student(const std::string& name, int age, const std::string& id)
    : name_(name), age_(age), id_(id) {}

Student::~Student() {}

void Student::addGrade(const std::shared_ptr<Grade>& grade) {
    grades_.push_back(grade);
}

std::vector<std::shared_ptr<Grade>> Student::getGrades() const {
    return grades_;
}

持久化存储

为了实现持久化存储,我们可以使用文件系统来保存学生的信息。这里我们将使用简单的文本文件来保存数据。

storage.h
#ifndef STORAGE_H
#define STORAGE_H

#include <fstream>
#include <sstream>
#include <vector>
#include <memory>
#include "student.h"

class Storage {
public:
    static bool saveStudentsToFile(const std::vector<std::shared_ptr<Student>>& students, const std::string& filename);
    static std::vector<std::shared_ptr<Student>> loadStudentsFromFile(const std::string& filename);
};

#endif // STORAGE_H
storage.cpp
#include "storage.h"
#include <iostream>

bool Storage::saveStudentsToFile(const std::vector<std::shared_ptr<Student>>& students, const std::string& filename) {
    std::ofstream file(filename);
    if (!file.is_open()) {
        return false;
    }

    for (const auto& student : students) {
        file << student->getName() << ' ' << student->getAge() << ' ' << student->getId() << '\n';
        for (const auto& grade : student->getGrades()) {
            file << grade->getSubject() << ' ' << grade->getScore() << '\n';
        }
        file << "END\n";
    }

    return true;
}

std::vector<std::shared_ptr<Student>> Storage::loadStudentsFromFile(const std::string& filename) {
    std::ifstream file(filename);
    std::vector<std::shared_ptr<Student>> students;

    if (!file.is_open()) {
        return students;
    }

    std::string line;
    while (std::getline(file, line)) {
        if (line == "END") {
            continue;
        }

        if (students.empty() || !students.back()->getGrades().empty()) {
            std::istringstream iss(line);
            std::string name;
            int age;
            std::string id;
            iss >> name >> age >> id;
            auto student = std::make_shared<Student>(name, age, id);
            students.push_back(student);
        } else {
            std::istringstream iss(line);
            std::string subject;
            double score;
            iss >> subject >> score;
            auto grade = std::make_shared<Grade>(subject, score);
            students.back()->addGrade(grade);
        }
    }

    return students;
}

更新主程序

我们需要更新 main.cpp 来集成成绩管理和持久化存储的功能。

main.cpp (更新)
#include <iostream>
#include <memory>
#include <vector>
#include "student.h"
#include "student_database.h"
#include "storage.h"

int main() {
    StudentDatabase db;
    const std::string filename = "students.dat";

    // Load data from file if exists
    auto loadedStudents = Storage::loadStudentsFromFile(filename);
    for (const auto& student : loadedStudents) {
        db.addStudent(student);
    }

    while (true) {
        std::cout << "1. Add Student" << std::endl;
        std::cout << "2. Remove Student" << std::endl;
        std::cout << "3. Find Student" << std::endl;
        std::cout << "4. Update Student" << std::endl;
        std::cout << "5. List All Students" << std::endl;
        std::cout << "6. Add Grade" << std::endl;
        std::cout << "7. Save and Exit" << std::endl;
        std::cout << "Enter your choice: ";
        int choice;
        std::cin >> choice;

        switch (choice) {
            case 1: {
                std::string name, id;
                int age;
                std::cout << "Enter name: ";
                std::cin >> name;
                std::cout << "Enter age: ";
                std::cin >> age;
                std::cout << "Enter ID: ";
                std::cin >> id;
                auto student = std::make_shared<Student>(name, age, id);
                db.addStudent(student);
                break;
            }
            case 2: {
                std::string id;
                std::cout << "Enter ID to remove: ";
                std::cin >> id;
                db.removeStudent(id);
                break;
            }
            case 3: {
                std::string id;
                std::cout << "Enter ID to find: ";
                std::cin >> id;
                auto student = db.findStudentById(id);
                if (student) {
                    std::cout << "Name: " << student->getName() << std::endl;
                    std::cout << "Age: " << student->getAge() << std::endl;
                    std::cout << "ID: " << student->getId() << std::endl;
                    std::cout << "Grades:" << std::endl;
                    for (const auto& grade : student->getGrades()) {
                        std::cout << "Subject: " << grade->getSubject() << ", Score: " << grade->getScore() << std::endl;
                    }
                } else {
                    std::cout << "Student not found." << std::endl;
                }
                break;
            }
            case 4: {
                std::string id;
                std::cout << "Enter ID to update: ";
                std::cin >> id;
                auto student = db.findStudentById(id);
                if (student) {
                    std::string newName, newId;
                    int newAge;
                    std::cout << "Enter new name: ";
                    std::cin >> newName;
                    std::cout << "Enter new age: ";
                    std::cin >> newAge;
                    std::cout << "Enter new ID: ";
                    std::cin >> newId;
                    auto newStudent = std::make_shared<Student>(newName, newAge, newId);
                    db.updateStudent(id, newStudent);
                } else {
                    std::cout << "Student not found." << std::endl;
                }
                break;
            }
            case 5: {
                auto students = db.getAllStudents();
                for (auto& student : students) {
                    std::cout << "Name: " << student->getName() << std::endl;
                    std::cout << "Age: " << student->getAge() << std::endl;
                    std::cout << "ID: " << student->getId() << std::endl;
                    std::cout << "Grades:" << std::endl;
                    for (const auto& grade : student->getGrades()) {
                        std::cout << "Subject: " << grade->getSubject() << ", Score: " << grade->getScore() << std::endl;
                    }
                    std::cout << "-----------------" << std::endl;
                }
                break;
            }
            case 6: {
                std::string id, subject;
                double score;
                std::cout << "Enter ID of the student: ";
                std::cin >> id;
                std::cout << "Enter subject: ";
                std::cin >> subject;
                std::cout << "Enter score: ";
                std::cin >> score;
                auto student = db.findStudentById(id);
                if (student) {
                    auto grade = std::make_shared<Grade>(subject, score);
                    student->addGrade(grade);
                } else {
                    std::cout << "Student not found." << std::endl;
                }
                break;
            }
            case 7: {
                auto students = db.getAllStudents();
                Storage::saveStudentsToFile(students, filename);
                return 0;
            }
            default:
                std::cout << "Invalid choice. Please try again." << std::endl;
        }
    }

    return 0;
}

编译和运行

使用 CMake 构建这个项目,可以在 CMakeLists.txt 中添加如下内容:

cmake_minimum_required(VERSION 3.10)
project(StudentInfoSystem VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)

add_executable(student_info_system main.cpp student.cpp student_database.cpp grade.cpp storage.cpp)
target_include_directories(student_info_system PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

然后,在终端中运行以下命令:

mkdir build
cd build
cmake ..
make
./student_info_system

现在你有了一个更加完整的学生信息管理系统,它可以管理学生的个人信息和成绩,并能够将数据保存到文件中。你可以根据需要继续扩展和改进这个系统。

😍😍 海量H5小游戏、微信小游戏、Web casualgame源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极致人生-010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值