用于转发协同返回的C ++抽象基本模板

时间:2013-09-07 23:29:35

标签: c++ crtp

我正在尝试使用CRTP和协方差来实现转发:

class Display {  // interface
    virtual Display& drawCircle(...) = 0;
    virtual Display& drawRect(...) = 0;
    // etc. lots of these.
};
class ADisplay<R> : public Display {
     virtual Display& getWrapped();
     virtual R& drawCircle(...) { getWrapped().drawCircle(...); return *this; }
     virtual R& drawRect(...) { getWrapped().drawRect(...); return *this; }
     // etc?
};
class B : public ADisplay<B> {
     Display& wrapped;
     virtual Display& getWrapped() { return wrapped; }
     B& methodSpecificToB() {...}
};

这将用于“构建器”样式:

B b;
b.drawCircle(1,2,3)
 .drawRect(4,5,6)
 .methodSpecificToB();

这可能并不令人惊讶,因为ADisplay&lt; B&gt;在实例化时是not completely defined

你能想到其他一些方法吗?

2 个答案:

答案 0 :(得分:1)

就像一个提示(我现在不想完全详细说明,它在我身边已经很晚了),你可以随时做(注意而没有抽象的Display接口):

template<class R>
class ADisplay<R> 
{
public:
    R& drawCircle(...) 
    { 
        static_cast<R*>(this)->drawCircleImpl(...); 
        return *static_cast<R*>(this); 
    }
    R& drawRect(...) 
    { 
        static_cast<R*>(this)->drawRectImpl(...); 
        return *static_cast<R*>(this); 
    }
protected:
    R& drawCircleImpl(...)
    {
        // May be have some static assert here, if you want to have this method
        // 'abstract'. Otherwise provide some reasonable base implementation, or
        // delegate to a mixin (provided as another template parameter)
    }

    R& drawRectImpl(...)
    {  
        // Same as above ...
    }
};

抽象接口的目的是什么,客户端必须知道具体的实现方法呢?

答案 1 :(得分:0)

这些功能:

virtual R& drawCircle(...) { getWrapped()->drawCircle(...); return *this; }
virtual R& drawRect(...) { getWrapped()->drawRect(...); return *this; }

应该是:

virtual ADisplay<R>& drawCircle(...) { getWrapped()->drawCircle(...); return *this; }
virtual ADisplay<R>& drawRect(...) { getWrapped()->drawRect(...); return *this; }