子类对象作为虚拟函数的参数

Subclass object as a parameter to a virtual function

本文关键字:函数 参数 虚拟 对象 子类      更新时间:2023-10-16

好的,所以基本上我在另一个类中使用了一个类,它要求对象报告它与另一个相同类型对象的关系。效果很好。仅供参考,这个类代表一个协议。不幸的是,现在我正试图通过添加一个名为Wrapper的类来修饰类关系。这个类的主要功能是它可以将第一个类作为一个参数(或任何其他类似的参数)

template< class InnerInterpreter >
class WrapperInterpreter
{
public:
    WrapperInterpreter(const InnerInterpreter &m) : innerMessage(m) {}
    ...
    virtual bool respondsToMessage(const WrapperInterpreter<InnerInterpreter> &) const = 0;
public:
    //member
    InnerInterpreter innerMessage;
};

出于其他设计原因,我得出的结论是,将其作为一组包装器的基类(而不是将两个不同的协议作为自变量),可以让我获得一组外部和内部协议类的组合。

所以我的问题是:当我尝试对WrapperInterpreter<>进行子类化,特别是为respondsToMessage()提供实现时,我最终得到的子类能够与WrapperInterpreter继承中的任何类进行比较。但这并不是我真正想做的。我想做的是强迫子类实现这样一个方法:

template< class Inner >
class ConcreteWrapper : WrapperInterpreter<Inner>
{
    ...
    bool respondsToMessage(const ConcreteWrapper<Inner> &);
    ...
}

我立即想到的一个解决方案是简单地将其从WrapperInterpreter的接口中删除,只让编译器在与其他设计一起使用时抱怨缺少接口方法。

所以我的问题是有没有办法把一个方法放在抽象类的接口中,这样子类就必须把子类类型的对象作为参数

或者,我是否试图错误地使用继承?有人有什么有用的设计模式可以帮助我解决这个问题吗?

有一种称为CRTP(奇怪的递归模板模式)的设计,它包括将Child的类型作为模板参数传递给Parent

template <typename Child>
class WrapperInterpreter {
    using Inner = typename Child::Inner; // nested typedef
    WrapperInterpreter(Inner const& ...);
    virtual bool respondsToMessage(Child const& ...) = 0;
};
template <typename Inner>
class Concrete: public WrapperInterpreter< Concrete<Inner> > {
    virtual bool respondsToMessage(Concrete const& ...) override;
};