2 类 可以互相指向对方吗?
Is it ok for 2 classes to have field pointing eachother?
所以我有 类 User
和 Job
:
class User {
string user_name;
Job* job;
};
class Job {
string job_type;
int salary;
User* user;
};
这样的设计有什么问题吗?我有大量 Job
s 和 User
s,我想快速访问用户的工作或正在工作的用户。这些 类 的字段可以相互指向吗?
没关系。例如,您需要小心谨慎地管理指针以避免泄漏。但这是完全合理的。
在 oop 的世界里,这是常见的情况。例如,典型的 GUI 架构以类似的方式使用这种方法,例如:
Widget 了解其父级。它保持指向父级的指针。
复合小部件知道其 z 排序的子项(小部件)
我明白了,这样的例子与你的post相去甚远。它只是显示大小写。
我不知道您的应用程序的确切架构。但也许 Job class 不应该知道用户?它减少了额外的关系并简化了内存管理(而不是用于更好地控制共享指针和弱指针)
只要 User
不拥有 Job
且 Job
不拥有 User
就可以了。
例如,您可能预先创建了 Job
和 User
的集合,然后想在它们之间创建关联:
#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]);
}
只要User
和Job
的集合同时被销毁,就不会有悬空指针的危险。如果指针是 const
指针可能更可取。
但如果您的意图是某种所有权,那么智能指针将是首选。
我有点惊讶大多数答案都说这个设计没问题。
除非有充分的理由(如性能要求),否则我认为这样做是不可接受的。
这是一种循环依赖,会影响代码的可读性和可测试性。但我主要担心的是,很难保持引用的一致性。
作为替代方案,我只提供一个参考,假设 User 有一个指向 Job 的指针。现在,如果您有一个工作并想找到相应的用户,您仍然可以搜索所有用户并找到具有指向此工作的指针的用户。当然,这比直接指针效率低,但在许多情况下无关紧要。可能更重要的是不会出现不一致。
所以我有 类 User
和 Job
:
class User {
string user_name;
Job* job;
};
class Job {
string job_type;
int salary;
User* user;
};
这样的设计有什么问题吗?我有大量 Job
s 和 User
s,我想快速访问用户的工作或正在工作的用户。这些 类 的字段可以相互指向吗?
没关系。例如,您需要小心谨慎地管理指针以避免泄漏。但这是完全合理的。
在 oop 的世界里,这是常见的情况。例如,典型的 GUI 架构以类似的方式使用这种方法,例如:
Widget 了解其父级。它保持指向父级的指针。
复合小部件知道其 z 排序的子项(小部件)
我明白了,这样的例子与你的post相去甚远。它只是显示大小写。
我不知道您的应用程序的确切架构。但也许 Job class 不应该知道用户?它减少了额外的关系并简化了内存管理(而不是用于更好地控制共享指针和弱指针)
只要 User
不拥有 Job
且 Job
不拥有 User
就可以了。
例如,您可能预先创建了 Job
和 User
的集合,然后想在它们之间创建关联:
#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]);
}
只要User
和Job
的集合同时被销毁,就不会有悬空指针的危险。如果指针是 const
指针可能更可取。
但如果您的意图是某种所有权,那么智能指针将是首选。
我有点惊讶大多数答案都说这个设计没问题。
除非有充分的理由(如性能要求),否则我认为这样做是不可接受的。
这是一种循环依赖,会影响代码的可读性和可测试性。但我主要担心的是,很难保持引用的一致性。
作为替代方案,我只提供一个参考,假设 User 有一个指向 Job 的指针。现在,如果您有一个工作并想找到相应的用户,您仍然可以搜索所有用户并找到具有指向此工作的指针的用户。当然,这比直接指针效率低,但在许多情况下无关紧要。可能更重要的是不会出现不一致。