我有一个多态值类型,如下实现:
class ShapeValue {
public:
template<class T>
ShapeValue(const T& value) {
obj = make_unique<holder<T>>(value);
}
// ... appropriate copy constructors and such
void draw() { obj->draw(); }
private:
struct base {
virtual ~base() {}
virtual void draw() = 0;
};
template<class T>
struct holder<T> : public base {
T value;
void draw() override { value.draw(); }
}
unique_ptr<base> obj;
};
如果你对这类事情不熟悉的话这是一个很好的谈话 https://youtu.be/QGcVXgEVMJg.
太棒了。但现在如果我想将底层对象转换为其他接口怎么办?
这是我的动机。以前,我以典型的方式定义了事物,如下所示:
class Shape {
virtual void draw() = 0;
};
然后我会定义其他接口,例如:
class HasColor {
virtual Color color() = 0;
virtual void setColor(Color) = 0;
};
所以我可以定义一个形状如下:
class MyShape : public Shape, public HasColor {
void draw() override;
Color color() override;
void setColor(Color) override;
};
因此,如果我有一堆选定的形状并且想要设置它们的颜色,我可以迭代所有形状并dynamic_cast<HasColor*>
。事实证明,这非常方便(顺便说一句,我的实际应用程序不是绘图应用程序,但具有类似的数据)。
我可以为我的多态值类型执行此操作吗?ShapeValue
接口不需要了解每一个Has
界面?我可以执行以下操作,这实际上并没有那么糟糕,但并不理想:
HasColor* ShapeValue::toHasColor() { return obj->toHasColor(); }