C ++对象层次结构依赖性代码设计

时间:2011-10-21 21:20:52

标签: c++ dependencies system-calls code-design

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

但是在这里我有了object_manager,它知道并保存所有对象,对象应该有一个创建新对象的选项,但是然后他们应该调用object_manager来强制它们知道它的存在,这将创建一个结构中的圆圈,这很糟糕。

这就像一个进程想通过调用OS系统调用来创建一个新进程,因此操作系统和进程知道对方..

我有没有办法在正确的代码设计中实现这一点,有时它应该是坏的?

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

6 个答案:

答案 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.hY.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文件。