如何将'this'作为参数传递给另一个没有循环依赖的类构造函数?

时间:2011-05-09 17:02:44

标签: c++ include dependencies strategy-pattern

我正在考虑策略模式(Design Patterns,GoF94),其中建议传递给策略构造函数的上下文可以是包含策略(作为成员)本身的对象。但以下情况不起作用:

//analysis.h

class StrategyBase;
class Strategy1;
class Strategy2;
class Analysis
{
   ...
      void ChooseStrategy();
   private:
      StrategyBase* _s;
      ...
};

//analysis.cpp

void Analysis::ChooseStrategy()
{
   if (...) _s = new Strategy1(this);
   else if (...) _s = new Strategy2(this);
   ...
}

//strategy.h

#include analysis.h
...

然后StrategyBase及其子类访问Analysis的数据成员。

这不起作用,因为在定义之前无法实例化Strategy *类。但它的定义取决于分析的定义。那么你应该怎么做呢?用

替换ChooseStrategy
void SetStrategy(StrategyBase* s) { _s = s; }

并在#include analysis.h和strategy.h的文件中进行实例化?这里最好的做法是什么?

4 个答案:

答案 0 :(得分:6)

除了非常一般状态/策略之外,您将始终在状态/策略模式中具有循环依赖关系。但是你可以限制相应的其他类的in-size (Lakos) use,使其至少编译:

  1. 转发声明Analysisanalysis.hstrategies.h
  2. 定义StrategyBase和子类(不要使用Analysis的内联方法)(strategies.h
  3. 定义Analysis(可能已使用使用策略的内联方法)(analysis.h
  4. 实施Analysis和策略类的非内联方法(analysis.cpp

答案 1 :(得分:3)

analysis.cpp还需要包含strategy.h来获取策略的完整定义。由于它是源文件,因此没有循环依赖。

答案 2 :(得分:1)

如果您传递指针(或引用),则无需实例化类:使用Forward Declaration

答案 3 :(得分:0)

有时很难弄清楚c ++的一个重要特性是需要以正确的顺序为编译器提供类。类之间的依赖关系决定了需要使用哪个顺序。它不会让人们想要将每个类放在单独的.h文件中变得更容易,因此在决定#include的顺序时,需要多次提供类的顺序。虽然人们正在学习标题和类依赖关系,但建议将每个类放在同一个.h文件中,因为这会迫使您只决定一次。在学习了正确的顺序之后,您可以再次开始使用将所有类放在单独的头文件中的良好约定。

相关问题