2012-02-27 97 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