4

我想创建两个类:object 和 object_manager,但我对它们应该如何查看/包含彼此感到困惑。我听说禁止两个标题相互包含,如果我的代码依赖项有圆圈,那么这是一个糟糕的代码设计,通常它应该像一个层次结构(城镇->房屋->家具和家具不应该知道关于城镇的存在)。

但是在这里我有 object_manager 知道并保存所有对象,并且对象应该有一个创建新对象的选项,但是他们应该调用 object_manager 这将迫使他们知道它的存在,这将在结构不好。。

这就像一个进程想通过调用操作系统系统调用来创建一个新进程,所以操作系统和进程彼此了解。

有没有办法可以在正确的代码设计中实现它,或者有时它应该是坏的?

我想也许这些对象应该有一个特殊的地方来存储他们所有的“系统调用”,并且 object_manager 会不时检查它..但也许有更好的方法。

4

6 回答 6

1

使用前向声明:

class ObjectManager;

class Object
{
private:
   ObjectManager* m_objManager;
   ....
public:
   ....
};

在 .cpp 文件中,您可以包含 ObjectManager.h 也可以代替 ObjectManager 制作接口,这将为您提供更多的实现 IObjectManager 的抽象...

祝你好运 :)。

于 2011-10-21T21:35:08.740 回答
1

其实两者都可以实现。不,这并不是很糟糕。这是一些部分代码。

假设你有一个头文件

我的对象.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

对象管理器的实现

#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);
}
于 2011-10-21T21:36:10.743 回答
0

CPP文件可以包含彼此的标头而不会导致编译问题(从设计的角度来看是否正确是另一回事,但在您的情况下应该没问题)。这意味着他们可以调用彼此的方法等。

关于文件,“object manager”头文件很可能包含“object”头文件,因为“object manager”类需要与“object”类实例一起工作。如果“object”头文件需要知道“object manager”类,在“object”头文件中放置“object manager”的前向声明。这样,您可以在“对象”头文件中使用指向“对象管理器”的指针和引用,而无需创建循环包含依赖项。

于 2011-10-21T21:29:52.927 回答
0

以下是一些消除标头之间耦合的一般建议:

转发 声明你能做什么。有时,您的 A 类仅通过传递引用或指针来使用其他类(X、Y、..)。因此,您A.h可以声明使用这些 X、Y 返回或参数类型的方法,而编译器不需要知道完整的类型。这意味着A.h不需要包括X.hY.h

使用 PImpl idioms,有时将实现与接口分离(不使用虚拟或抽象类)的最佳方法是执行以下操作:


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();
}
于 2011-10-21T21:30:46.043 回答
0

在很多情况下,类需要相互了解。唯一的问题是他们必须部分了解彼此,或者至少有一个班级了解。通常解决问题的方法是使用前向声明。唯一棘手的问题是在 A 类中,您不能声明具有 B 类类型的成员只有一个指针或对 B 类的引用。

class B;
class A 
{
   B* oB;

};

class B
{
   A oA;
}:
于 2011-10-21T21:32:41.397 回答
0

What you're describing is an object that can only exist inside another object.

A good way to implement this is with nested classes:

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; }
};

Keep in mind that you can still have 2 cpp files for object and object_manager.

于 2011-10-21T21:45:25.223 回答