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/