2017-08-25 42 views
0

我尝试重写基类函数,但是因为我已经模板化了它的子类/派生类/子类,我无法重写该函数,具体取决于我实例化的类型带有的模板。我不能重写Base类的方法,因为我的派生类是模板化的

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 
} 

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

我也想过templatising Base并让它从一个更高的父母(它没有被模板化)继承,但我遇到了同样的问题。

有没有办法解决这个问题?

+1

“*我不能重写基类的方法,因为我的派生类是模板化的*”这不是你无法重写的原因。 – juanchopanza

+0

对不起,我意识到这听起来如此,你是对的。不仅仅是因为我对它进行了模板化,因为我得到了依赖于模板参数的返回类型。 – Zebrafish

+1

为什么你需要*重写一个纯虚函数?对我来说,你在混合静态和动态多态。 – Bathsheba

回答

2

可以做到这一点,如果返回值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的子类:这种关系mea ns T&是与Cov&共变的返回类型,因此编译将会成功。这样做也可以避免使用T的值副本。您可能还会发现,为各种T构建转换运算符很方便,最终生成具有原始类型返回值的运算符。

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

+0

从答案中的示例代码中,'int'和'double'都不是'Cov'的子类。如果没有在答案中没有解释的额外机器,它不会解决问题。 – skypjack

+0

这非常有趣。 Covariant是Visual Studio使用的词,它表示它必须是协变的。这看起来很有趣,我会看看我能做些什么。 – Zebrafish

+0

@skypjack是的,这是我想到的第一件事,然后我想我只是将原始数据类型包装在类中。哇,有无止境的解决方案。好的,这可能是一个坏主意,但我仍然很喜欢看到这可能会有多疯狂。 – Zebrafish

2

BaseType有一个对所有后代有约束力的合同。它说,getPropertyValue返回doubleNumberType没有得到修改合同,它是成立的。

让我们假设合同是不存在的。

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一个易用的界面,并坚持下去的所有派生类。

+0

是的,这是明智的。有一个upvote。 – Bathsheba

相关问题