首页 > 解决方案 > 从基类方法返回对派生类的引用

问题描述

我的任务是实现一个简单的 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++ 中实现?

在这里进一步讨论

标签: c++inheritance

解决方案


如果您想共享实现保留类型信息,那么您需要 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);
}

在 Wandbox 上现场观看


推荐阅读