2

我正在尝试使用 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() {...}
};

这将用于“builder”风格:

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

这也许并不奇怪,因为 ADisplay<B>在实例化时没有完全定义

你能想出其他方法来做到这一点吗?

4

2 回答 2

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 ...
    }
};

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

于 2013-09-08T00:32:39.283 回答
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; }
于 2013-09-07T23:34:39.520 回答