I have a task to implement a simple SVG generator. I need to support Circle, Polyline and Text. All three have at least 4 common methods: - SetStrokeColor - SetFillColor - SetStrokeWidth - ToString One of the main requirements is to support chaining, e.g.: Polyline{}.SetStrokeColor("white").SetFillColor("black")...
I decided to implement a base class Element, which all the other classes inherit from. The idea is to have a class Document that holds a vector of all the elements added to the document. A sample signature for a base method:
// source of trouble
Element &SetStrokeColor(const Color &color) {
...
return *this;
}
Run Code Online (Sandbox Code Playgroud)
My derived classes do call these methods, but the trouble is that the methods return a reference to the base class Element, not the derived class.
My question is whether it is all together possible to implement in c++???
如果要共享实现并保留类型信息,则需要CRTP:
struct ElementBase { };
template <class Concrete>
struct Element : ElementBase {
Concrete &setStrokeWidth(int width) {
// Actual implementation...
(void) width;
return cthis();
}
private:
friend Concrete;
Element() = default;
Concrete &cthis() { return static_cast<Concrete &>(*this); }
Concrete &cthis() const { return static_cast<Concrete const &>(*this); }
};
struct Circle : Element<Circle> {
Circle &SetCircleCenter(int x, int y) {
// Actual implementation...
(void) x;
(void) y;
return *this;
}
};
int main() {
Circle c;
c.setStrokeWidth(4).SetCircleCenter(0, 0);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |