我想创建两个类:object和object_manager但我对他们应该如何看待/包含彼此感到困惑。我听说禁止两个标题相互包含,如果我的代码依赖项有圆圈,那么这是一个糟糕的代码设计,通常它应该像一个层次结构(town-> house->家具和家具不应该'了解城镇的存在。)
但是在这里我有了object_manager,它知道并保存所有对象,对象应该有一个创建新对象的选项,但是然后他们应该调用object_manager来强制它们知道它的存在,这将创建一个结构中的圆圈,这很糟糕。
这就像一个进程想通过调用OS系统调用来创建一个新进程,因此操作系统和进程知道对方..
我有没有办法在正确的代码设计中实现这一点,有时它应该是坏的?
我想也许对象应该有一个特殊的地方,他们将存储所有的“系统调用”,而object_manager会不时地检查它......但也许有更好的方法。
答案 0 :(得分:1)
使用前瞻声明:
class ObjectManager;
class Object
{
private:
ObjectManager* m_objManager;
....
public:
....
};
在.cpp文件中,您可以包含ObjectManager.h 而且,而不是ObjectManager使接口,将为您提供更多的实现IObjectManager抽象...
祝你好运:)。答案 1 :(得分:1)
实际上可以实现这两者。不,这不是很糟糕。这是一些部分代码。
假设你有一个头文件
myobject.h
#ifndef _MYOBJECT
#define _MYOBJECT
// Declare the Object Manager class in it.
class MyObjectManager; // forward declaration
class MyObject {
MyObjectManager manager;
registerSelf(MyObjectManager &m);
}
#endif _MYOBJECT
现在为ObjectManager标题
#ifndef _MYOBJECT_MANAGER
#define _MYOBJECT_MANAGER
class MyObject; // forward declaration
class MyObjectManager {
private:
List list[];
public:
registerObject(MyObject &o);
};
#endif
objectmanager的实现
#include <myobject>
#include <myobjectmanager>
MyObjectManager::manageMyObject(MyObject &o) {
list += o; /* etc. */
}
对象的实现
#include <myobject>
#include <myobjectmanager>
MyObject::registerSelf(MyObjectManager &manager) {
this.manager = manager;
manager.registerObject(*this);
}
答案 2 :(得分:0)
CPP 文件可以包含彼此的标题而不会导致编译问题(从设计的角度来看它是否正确是另一回事,但在你的情况下应该没问题)。这意味着他们可以调用彼此的方法等。
关于头文件,“对象管理器”头很可能包含“对象”头,因为“对象管理器”类需要使用“对象”类实例。如果“对象”头文件需要知道“对象管理器”类,则在“对象”头文件中放置“对象管理器”的前向声明。这样,您可以使用“对象”头文件中的“对象管理器”的指针和引用,而无需创建循环包含依赖项。
答案 3 :(得分:0)
删除标题之间耦合的一些一般建议如下:
转发声明您可以的内容。有时您的A类仅通过传递引用或指针来使用其他类(X,Y,..)。因此,在A.h
中,您可以声明使用这些X,Y返回或参数类型的方法,而无需编译器知道完整类型。这意味着A.h
不需要包含X.h
或Y.h
使用PImpl惯用法,有时,将实现与接口分离(不使用虚拟或抽象类)的最佳方法是执行以下操作:
foo.h中
class Foo {
struct Impl;
Impl* m_impl;
public:
Foo();
void SomeMethod();
}
Foo.cpp中
#include "X.h"
struct Foo::Impl {
/* actual implementation */
...};
Foo::Foo() : m_impl( new Foo::Impl() ) {};
void Foo::SomeMethod() {
m_impl->SomeMethod();
}
答案 4 :(得分:0)
在很多情况下,课程需要彼此了解。唯一的问题是他们必须部分或至少一个班级相互了解。通常解决问题的方法是使用forward declarations。唯一棘手的问题是在A类中,你不能声明一个类B只有一个指针或对B类的引用的成员。
class B;
class A
{
B* oB;
};
class B
{
A oA;
}:
答案 5 :(得分:0)
您所描述的是只能存在于另一个对象中的对象。
实现这一点的一个好方法是使用嵌套类:
class object_manager {
public:
class object { // object_manager::object. public allows it to be used outside of manager
public:
void foo() {
object* t = construct(); // can call object_manager methods
}
};
private:
object my_objects[5]; // can create objects
static object* construct() { return NULL; }
};
请记住,对象和object_manager仍然可以有2个cpp文件。