2个课程是否可以互相指向字段?

时间:2016-11-20 05:02:12

标签: c++ class oop pointers class-design

所以我有课程UserJob

class User {
 string user_name;
 Job* job;
};

class Job {
 string job_type;
 int salary;
 User* user;
};

这种设计有什么问题吗?我有大量的JobUser,我希望能够快速访问用户的工作或正在工作的用户。这些类的字段相互之间是否合适?

4 个答案:

答案 0 :(得分:3)

没关系。例如,您需要小心谨慎地管理指针以避免泄漏。但这完全合理。

答案 1 :(得分:1)

只要User不拥有JobJob不拥有User,那么这很好。

例如,您可能预先创建了JobUser的集合,然后想要在它们之间创建关联:

#include <string>
#include <vector>

class Job;

class User {
    std::string user_name;
    Job* job;
  public:
    explicit User(const std::string& user_name) : user_name(user_name) {}
    void setJob(Job& job) { this->job = &job; }
};

class Job {
    std::string job_type;
    int salary;
    User* user;
  public:
    Job(const std::string& job_type, int salary) : job_type(job_type), salary(salary) {}
    void setUser(User& user) { this->user = &user; }
};

void recruit(User& user, Job& job) {
  user.setJob(job);
  job.setUser(user);
}

int main() {
    auto jobs = std::vector<Job>{ {"Tinker", 10'000}, {"Tailor", 20'000}};
    auto users = std::vector<User> {User{"George"}, User{"Percy"}};
    recruit(users[0], jobs[1]);
    recruit(users[1], jobs[0]);
}

只要UserJob的集合同时被销毁,就没有悬挂指针的危险。如果指针是const指针,那可能更好。

但如果你的意图是某种所有权,那么智能指针将是首选。

答案 2 :(得分:0)

在oop的世界是正常的状况。例如,典型的GUI架构以类似的方式使用这种方法,如:

  1. Widget知道它的父级。它保持指向父级的指针。

  2. 复合小部件知道它的z有序子级(小部件)

  3. 我明白,这样的例子远非你的帖子。它只是显示案例。

    我不知道您的应用程序的确切架构。但也许Job类不应该知道用户?它减少了额外的关系并简化了内存管理(而不是用于更好地控制共享和弱指针)

答案 3 :(得分:0)

我有点惊讶,大多数答案都说这个设计没问题。

我认为这是不可接受的,除非有很好的理由(如性能要求)这样做。

这是一种循环依赖,会损害代码的可读性和可测试性。但我主要关注的是保持参考文献的一致性非常困难。

作为替代方案,我只提供一个引用,比如用户有一个指向Job的指针。现在,如果您有一个Job并想要找到相应的User,您仍然可以搜索所有用户并查找具有指向此Job的指针。当然,这比直接指针效率低,但在许多情况下它并不重要。可能更重要的是不会出现不一致的情况。