从使用模板的 class 继承时如何覆盖方法?

How to override methods when inheriting from a class that uses templates?

我在尝试弄清楚如何正确编写既继承自使用模板的 class 又重写虚拟方法的 class 时遇到了麻烦。当我尝试创建此 class 的实例时,Visual Studio 给我一个错误提示

object of abstract type PropertyReal is not allowed: 
pure virtual function "Property<T>::propertyId [width t=qreal]" has no overrider

这是我的代码

template <typename T>
class Property
{
    T  _value;

public:
    Property(T initValue);
    ~Property();

    virtual QString propertyId() = 0;

    virtual T value() { return _value; }
    virtual void setValue(T value) { _value = value; }
};


template<typename T> 
Property::Property(T initValue)
    :_value(initValue)
{
}


template<typename T> 
Property::~Property()
{
}




class PropertyReal : public Property<qreal>
{
    static const QString ID;

public:
    PropertyReal();
    ~PropertyReal();

    template <qreal>
    QString propertyId() { return ID; }
};

const QString PropertyReal::ID = "real";

PropertyReal::PropertyReal()
{
}

PropertyReal::~PropertyReal()
{
}



class RectComp : Component
{
public:
    static const QString ID;

    PropertyReal _width;

public:
    RectComp();
    ~RectComp();

    QString componentId() { return ID;  }
};

声明字段PropertyReal _width时出现错误。我该如何解决这个问题?

尝试删除 template <qreal> 部分。

简单写

QString propertyId() { return ID; }

重点是虚拟蚂蚁模板方法不匹配。您不能创建虚拟模板方法,模板方法也不能覆盖虚拟 class.

对于其他虚方法

virtual T value() { return _value; }
virtual void setValue(T value) { _value = value; }

依赖于 Property class 的模板 T 参数,您必须匹配传递给基础 class 的模板参数。

我的意思是...因为PropertyReal继承自Property<qreal>,你可以覆盖value()setValue()如下

qreal value () { /* something */ }
void setValue (qreal value) { /* something */ }
QString propertyId() override { return ID; }

应该可以正常工作。

参见简化示例:ideone

像这样:

class PropertyReal : public Property<qreal>
{
    static const QString ID;

public:
    PropertyReal();
    ~PropertyReal();

    // note: this is not a template!
    QString propertyId() override { return ID; }
};

override 关键字不是必需的,但添加它是一种很好的做法。

在您的示例中 Property 不是 class,而是 class 模板 。您从(隐式)实例化的 class Property<qreal> 派生 PropertyReal - 当您在 Property 中使用 T 时,您应该在中使用 qreal PropertyReal.