2011-10-21 63 views
4

我想創建兩個類:object和object_manager,但我很困惑他們應該如何看待/包含對方。我聽說兩個頭文件被禁止相互包含,如果我的代碼依賴包含了圓圈,那麼這是一個糟糕的代碼設計,通常它應該像一個層次結構(鎮 - >家 - >傢俱和傢俱不應該知道關於城鎮的存在)。C++對象層次依賴關係代碼設計

但是在這裏我有了知道並擁有所有對象的object_manager,並且對象應該有一個選項來創建新的對象,但是他們應該調用object_manager來強制它們知道它的存在,這會創建在結構上轉了一圈,這是壞..

這就像一個流程要通過調用OS系統調用創建一個新的過程,所以OS和進程知道對方..

是有一種方法,我可以在正確的代碼設計中實現這一點,或者有時它應該是壞的?

我想也許對象應該有一個特殊的地方,他們將存儲他們所有的「系統調用」,並且object_manager會不時檢查它..但也許有更好的方法。

+5

+1爲「無政府結構」 – AJG85

回答

1

使用前向聲明:

class ObjectManager; 

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

在.cpp文件中,您可以包含ObjectManager.h 而不是ObjectManager製作接口,它將爲您提供更多的實現IObjectManager抽象...

祝您好運:)。

0

CPP文件可以包含對方的頭文件而不會導致編譯問題(從設計的角度來看是否正確是一個不同的問題,但在年度情況下應該可以)。這意味着他們可以相互調用的方法等

關於文件,「對象管理器」頭將最有可能包括「對象」標頭,因爲「對象管理器」類需要使用「對象工作「類實例。如果「對象」頭文件需要知道「對象管理器」類,請在「對象」頭文件中放置「對象管理器」的前向聲明。這樣,您可以在「對象」頭文件中使用指針和對「對象管理器」的引用,而不會創建循環包含依賴項。

0

一些一般性的建議,杜絕之間的耦合頭如下:

正向聲明一下就可以了。有時你的A類只通過傳遞引用或指針來使用其他類(X,Y,..)。因此,在您的A.h中,您可以聲明使用這些X,Y返回或參數類型的方法,而無需編譯器知道完整類型。這意味着,A.h並不需要包括X.hY.h

使用平普爾成語,有時去耦接口實現(不使用虛擬的或抽象類),最好的辦法是做這樣的事情:


了foo.h

class Foo { 
struct Impl; 
Impl* m_impl; 

public: 
Foo(); 
void SomeMethod(); 

} 

富。 cpp

#include "X.h" 
struct Foo::Impl { 
/* actual implementation */ 
...}; 

Foo::Foo() : m_impl(new Foo::Impl()) {}; 

void Foo::SomeMethod() { 
m_impl->SomeMethod(); 
} 
0

在許多情況下,類需要彼此瞭解。唯一的問題是他們必須相互瞭解部分或至少有一個班級。通常解決問題的方式是使用forward declarations。唯一的最艱難的問題是A類不能聲明其類型爲B類只有一個指針或B級的參考成員

class B; 
class A 
{ 
    B* oB; 

}; 

class B 
{ 
    A oA; 
}: 
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. */ 
} 

的實現對象

​​
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文件。