我无法重写基类的方法,因为我的派生类是模板化的

I can't override Base class's method because my derived class is templatised

本文关键字:派生 我的 重写 基类 方法 因为      更新时间:2023-10-16

我尝试覆盖基类函数,但由于我已经模板化了它的子/派生/子类,所以我无法覆盖该函数,具体取决于我实例化模板的类型。

struct BaseType
{
virtual double getPropertyValue() = 0; 
};
template <typename T>
struct NumberType : BaseType
{
T propertyValue;
T getPropertyValue() override { return propertyValue; }  // I would like this to return whatever T is.
};
int main()
{
std::vector<BaseType*> vectr;
NumberType<double> doubleType;  // This is fine, overrides the base function
NumberType<int> intType;    // Has no overrider, won't compile
}

所以我想也许我也可以模板化基类,以便基类函数也返回 T。但是如果我这样做,我将无法将它们保存在容器中或指向它们,因为它们都是不同的 Base<类型>类型。

我还考虑过模板化 Base 并让它从更高的父级(不是模板化的(继承,但我遇到了同样的问题。

有什么办法吗?

如果返回值T与纯虚函数的返回值协,则可以执行此操作。但遗憾的是,T通常不会与double共变。

接受你混合了静态和动态多态技术,这可能是一个设计缺陷,你可以定义

struct Cov {};

struct BaseType
{
virtual Cov& getPropertyValue() = 0; 
};

然后

template <typename T>
struct NumberType : BaseType
{
T propertyValue;
T& getPropertyValue() override { return propertyValue; }
};

其中TCov的子类:这种关系意味着T&是与Cov&协变的返回类型,因此编译将成功。 这样做还可以避免T的价值副本被占用。您可能还会发现为最终构建具有基元类型返回值的各种T构建转换运算符很方便。

您还可以引入const引用返回类型以满足确切的要求。

BaseType有一个对其所有后代具有约束力的协定。它说getPropertyValue返回double.NumberType无法修改合同,但它是一成不变的。

让我们假设合同不存在。

BaseType& base = BaseContainer.getSome();
// base can be NumberType<complex> or 
// or NumberType<tensor<double,4,4,4>> or NumberType<padic<5>>
// or a type that is not even thought of yet 
// as of now.
what = base.getPropertyValue(); // how should 'what' be declared?

如果我们不知道base.getPropertyValue()的结果是什么,就没有办法使用它。

使返回类型协变并没有真正的帮助。它只是将问题从BaseType转移到BaseType::getPropertyValue()返回的任何基类。

您需要提出一个可用的BaseType接口,并在所有后代类中坚持使用它。