struct InkPen
{
  void Write()
  {
    this->WriteImplementation();
  }

  void WriteImplementation()
  {
    std::cout << "Writing using a inkpen" << std::endl;
  }

};

struct BoldPen
{
  void Write()
  {
    std::cout << "Writing using a boldpen" << std::endl;
  }
};

template<class PenType>
class Writer : public PenType
{
public:
  void StartWriting()
  {
    PenType::Write();
  }
};

int main()
{
  Writer<InkPen> writer;
  writer.StartWriting();
  Writer<BoldPen> writer1;
  writer1.StartWriting();
  return 0;
}

我在学习基于策略的设计时编写了以上代码。我对上面的代码有几个问题

1-此实现看起来正确吗?我的意思是:它真的看起来像基于策略的设计吗?

2-我现在可以将任何种类的笔钩到作家身上。但是,当我没有默认构造函数(只有参数化的构造函数)时,该怎么办?我将如何处理这种情况?
template<class PenType>
class Writer : public PenType
{
public:
  void StartWriting()
  {
    PenType::Write();
  }
};

3-使用上述代码时
Writer<InkPen> writer;

我猜编译器将用InkPen替换PenType。如果是,为什么我不能仅从StartWriting()调用Write()而不是给基类名称加上前缀(PenType::Write())?

4-我认为基于策略的设计会迫使您从语义上无效的类中派生。在上面的代码中,仅因为作家使用笔,所以作家是从笔派生的。但是说作家是一支笔在语义上是无效的。还有其他更好的方法可以解决此问题,或者我在这里丢失了一些东西?

有什么想法吗?

最佳答案

这是我实现类的方法:

template<class PenType>
class Writer
{
public:
  Writer(const PenType& pen = PenType()) : pen(pen) {}

  void StartWriting()
  {
    pen.Write();
  }

private:
  PenType pen;
};

这允许用户将特定的Pen对象传递给构造函数,如果该对象没有默认的构造函数,或者您不希望使用它,其次,如果您不使用PenType对象,则仍然可以很高兴让它使用默认构造函数创建一个。 C++标准库在许多类中都做同样的事情(例如,考虑容器类的分配器)。

我删除了继承。它似乎并没有真正添加任何东西(并且可能会引起问题。您可能不希望Writer类的用户直接调用PenType::Write函数。您可以使用私有(private)继承代替,但是通常,composition是更简单,更常规的设计。

通常,基于策略的设计不需要继承。将其添加为成员也一样。如果确实要继承,请将其设为私有(private),这样就不会遇到您提到的#4问题。

关于c++ - 基于策略的设计和最佳实践-C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/872675/

10-10 07:38