我的任务是实现一个简单的SVG生成器。我需要支持圆,折线和文本。这三种方法至少有四种:- SetStrokeColor - SetFillColor - SetStrokeWidth - ToString主要要求之一是支持链接,例如:例如:折线{}。SetStrokeColor(“白色”)。SetFillColor(“black”)。..
我决定实现一个基类Element,所有其他类都从它继承。这个想法是有一个类Document,它包含添加到文档中的所有元素的向量。基本方法的示例签名:
// source of trouble
Element &SetStrokeColor(const Color &color) {
...
return *this;
}
我的派生类确实调用了这些方法,但问题是这些方法返回的是对基类Element的引用,而不是对派生类的引用。
我的问题是,所有这些是否都可以在C++中实现???
Further discussion here
3条答案
按热度按时间bihw5rsg1#
如果你想共享实现 * 和 * 保存类型信息,CRTP就是你所需要的:
See it live on Wandbox
pod7payv2#
使用协变返回类型,您可以
在派生类中
当静态类型为
Derived
时,它允许您将Derived
示例作为Derived
示例处理(例如,例如在Derived
本身内部)。当静态类型是Element
时,refToThis()
的返回类型也是。wn9m85ua3#
比较:
返回
this
/*this
的指针或引用绝对没有区别,所以是的,你可以安全地这样做。编辑:
Circle().SetStrokeWidth(16).SetCircleCenter({0, 0})
. SetStrokeWidth返回对Element的引用,因此SetCircleCenter不可用。在这种情况下,你有点麻烦。就像lubgrdenoted一样,你可以通过使用协变返回类型来解决这个问题--是的,这意味着你必须单独覆盖每个函数。或者,您可以使用CRTP来保存所有这些麻烦:
对于这种方法,来自
Element
类的原始函数需要是 * 非 * 虚拟的(感谢@Quentin的提示;这实际上是一个优点,因为虚拟函数调用的成本更高。..);在模板中,参数(T
,i.例如Circle
)尚未完全定义(使用CRTP模式),编译器无法检查返回类型是否真的是协变的。所以实际上,我们只是隐藏了基类的函数。与覆盖相比,这仍然没有缺点:协变返回类型仅在(虚)函数直接在对象上调用时才可用: