c++ - 从基类方法返回对派生类的引用
问题描述
我的任务是实现一个简单的 SVG 生成器。我需要支持圆形、折线和文本。这三个都有至少 4 种常用方法: - SetStrokeColor - SetFillColor - SetStrokeWidth - ToString 主要要求之一是支持链接,例如: Polyline{}.SetStrokeColor("white").SetFillColor("black")...
我决定实现一个基类 Element,所有其他类都继承自它。这个想法是有一个类 Document ,它包含添加到文档中的所有元素的向量。基本方法的示例签名:
// source of trouble
Element &SetStrokeColor(const Color &color) {
...
return *this;
}
我的派生类确实调用了这些方法,但问题是这些方法返回对基类 Element 的引用,而不是派生类。
我的问题是是否可以在 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);
}
推荐阅读
- javascript - 使用ldapJS修改用户时如何动态传递属性
- git - 我可以将浅克隆设置为我的仓库的默认值吗?
- c++ - 单行在map中初始化一个C++对象
- android - 如何在应用 Flutter 上修复 ManiFest 中的错误
- java - openGattServer(context, mGattServerCallback) 似乎没有打开 gattserver,为什么?
- dialogflow-es - 我如何获得在 DialogFlow 上调用我的履行的意图?
- grammar - 令牌和规则之间的真正区别是什么?
- c - 这个宏可以描述基于数组的 UUID / GUID 文字吗?
- sql - 如何使数据类型为 Varchar 的字段成为 Snowflake 中的日期?
- python - 芹菜关闭工人并重试任务