首页 > 解决方案 > C++:如何通过这种方式建立结构之间的关系?

问题描述

我是 c+ 的初学者,我正在从事一个项目:“教育管理系统”,当我开始编写对象之间的关系以及它们相互访问的方式时,我发现困难和挣扎,所以这是我的方法:

struct doctor
{
    person info;
    vector <course> courses;
};

struct student
{
    person info;
    vector <course> courses;
    vector <assignmentSolution> assignmentSolutions;
};

struct course
{
    int code;
    string title;
    doctor lecturer;
    vector <student> registeredStudents;
    vector <assignment> assignments;
};


vector <doctor> doctors;
vector <student> students;
vector <course> courses;

因此,医生将通过以下方式创建课程:

courses.push_back(newCourse);
doctors[index].courses.push_back(newCourse);

这是错误的,但我想知道如何在内存中只创建一次,但请记住学生将在那之后注册课程。

标签: c++relationship

解决方案


可能有点过火了,但是使用访问者模式,您可以扩展课程系统:基本上,您有一个拥有课程的学校班级。学校成员可以通过调用 registerMember(code, member) 进行注册。课程本身并不拥有学校成员,只是指向他们的指针

#include <map>
#include <memory>
#include <string>
#include <vector>

struct Course;
struct School;

struct Person {
  std::string name;
  int age;
};

struct SchoolMember {
  Person info;  // composition unless person has functionality that SchoolMember
                // needs
  std::vector<Course*> courses;  // maybe map for easier deletion
  School* school;

  virtual ~SchoolMember() {}
  virtual void visit(Course* course) = 0;
};

struct Student;
struct Doctor;

struct Course {
  int code;
  std::string title;
  Doctor* mainDoctor;
  std::vector<Student*> students;

  virtual ~Course() {}

  virtual void accept(Student* student) = 0;
  virtual void accept(Doctor* doctor) = 0;

  virtual void cleanUp() {
    // remove me from student'S lists etc.
  }
};

struct Student final : SchoolMember {
  void visit(Course* course) override {
    courses.emplace_back(course);
    course->accept(this);
    // additional stuff
  }
};

struct Doctor final : SchoolMember {
  void visit(Course* course) override {
    courses.emplace_back(course);
    course->accept(this);
    // additional stuff
  }
};

struct Course101 final : Course {
  void accept(Student* student) {
    // Reject advanced students, etc.
    students.emplace_back(student);
  }
  void accept(Doctor* doctor) {
    // Replace current doctor
  }
};

struct CourseAdvanced final : Course {
  Doctor* secondaryDoctor;

  void accept(Student* student) {
    // Reject 101 students, etc.
    students.emplace_back(student);
  }
  void accept(Doctor* doctor) {
    // I can have multiple doctors!

  }
};

struct School {
  std::map<int, std::unique_ptr<Course>> courses; // School owns the courses

  void addCourse(int code /**/) {
    // create new course
  }

  void registerMember(int code, SchoolMember* member) {
    if(auto it = courses.find(code); it != courses.end()) {
      member->visit(it->second.get());
    }
  }

  void removeCourse(int code) {
    if(auto it = courses.find(code); it != courses.end()) {
      it->second->cleanUp();
      courses.erase(it);
    }
  }
};

推荐阅读