2012-02-27 140 views
1

我要去C++的這一個übern00b,並要求如何繼承時處理循環依賴的最佳方式。處理對繼承的循環依賴

該設置很簡單:場景類擴展Actor;場景有一個指向Actor的向量的指針; Actor有一個(父)場景的指針。

至於包括文件我:

Scene.h:

#include <string> 
#include <vector> 
using namespace std; 

#ifndef __Scene_h__ 
#define __Scene_h__ 

#include "Actor.h" 

namespace myns 
{ 
    // class Actor; 
    class Scene; 
} 

namespace myns 
{ 
    class Scene: public myns::Actor 
    { 
     /* private class attributes... */ 

     public: 
      /* public class attributes... */ 

      std::vector<myns::Actor*> actors; 

      Scene(/* arguments */); 

      /* public class methods... */ 
    }; 
} 

#endif 

Actor.h

#include <string> 
#include <vector> 
using namespace std; 

#ifndef __Actor_h__ 
#define __Actor_h__ 

#include "Scene.h" 

namespace myns 
{ 
    // class Scene; 
    class Actor; 
} 

namespace myns 
{ 
    class Actor 
    { 
     /* private class attributes... */ 

     public: 
      /* public class attributes... */ 

      myns::Scene* scene; 

      Actor(); 

      Actor(/* arguments */); 

      /* public class methods... */ 
    }; 
} 

#endif 

但是這給了我很多C2504錯誤/基類的視覺未定義Studio 2010.

如果我在Actor.h上評論Scene.h,並取消註釋forward.h演員Actor.h上的場景聲明它可以工作,但是在我的應用程序中,如果我想只在特定的一段代碼中包含Actor.h,它將不起作用。我怎樣才能在保持Actor.h的包含獨立性的情況下工作,包括Actor.h,而不需要事先手動包含Scene.h?

我的類定義有什麼問題,以及如何處理這種循環依賴的最佳方法?

不應該#ifndef指令防止這個包含問題?

在此先感謝。

回答

6

但後來,在我的應用程序,如果我想包括在一個特定的代碼塊只有Actor.h,它不會工作

你需要做的是在.cpp你需要的文件使用定義Actor類你必須include都是Actor.h Scene.h。這樣前向聲明將得到解決,一切都應該起作用。

另外,您應該將#ifndef#define右移到文件頂部,在include之前。另外,在頭文件中使用using是不好的做法,因爲其他文件include頭可能無法正常工作。儘管如此,它應該可以放入你的namespace myns { ... }之內。

+0

有沒有什麼辦法可以聲明我的類,以便我只能包含Actor.h當我只需要一個Actor(讓Actor.h負責它的依賴)? 這是依賴代理標準C++的做法嗎? 並假設所有這些類都是庫的一部分,最好的做法是使Library.h完成所有這些包括正確的順序,然後在我的應用程序中只包含Libray.h? – pedrosanta 2012-02-27 15:50:36

+1

實際上在任何情況下你都不需要包含兩個文件來使用'Actor',除了在Actor.cpp中,否則這就意味着你在Actor.h中使用'Scene',這不應該起作用,因爲你'我只得到了一份前瞻性聲明。 – spencercw 2012-02-27 15:53:27

+0

哦,好吧,我得到了最後的評論。是的,這很有道理,非常明確。 – pedrosanta 2012-02-27 16:00:22

1

是場景真的是一種類型的演員?

如果是這樣,演員可能不應該知道場景。基類通常不應該知道它們的派生類。

Liskov Substitution Principle在哪裏?你在一個Actor上執行什麼操作,這個操作符會被一個場景以不同方式多態地執行。

無論如何,Scene派生自Actor,所以必須包含它的基類。但是在Actor.h中,如果你真的需要Scene類,它只能是前向聲明。

在編譯單元(.cpp文件)中,如果需要,可以包含兩個標題。

+0

命名空間是一個錯字。 :)更正。 – pedrosanta 2012-02-27 15:53:26

+0

不是。場景擴展了演員(我需要演員屬性,如表現形式和行爲/後臺動作),所以它是一種特殊的(超級)演員。但是演員又放置在一個場景上,需要與場景交流(終止場景等)。 我要檢查一下這個原理並回復給你。 – pedrosanta 2012-02-27 15:58:40