虚函数返回类型
Virtual function return type
我在基类中将纯虚函数定义为虚拟int GetData() const = 0
;
在每个派生类中,我定义了一个enum,并尝试覆盖GetData函数return(派生类特定的enum)值;
例如:class Derived1 : public Base
{
public :
enum D1
{
d1_1 = 0,
d1_2 = 60,
...
d1_100
};
D1 GetData () const;
};
class Derived2 : public Base
{
public :
enum D2
{
d2_1 = 10,
d2_2 = 39,
...
d2_300
};
D2 GetData () const;
};
很重要的一点是,我不能为所有类的所有枚举值定义相同的范围。上面的代码会产生编译错误:
error C2555: : overriding virtual function return type differs and is not covariant
有什么建议-如何解决这个问题?
在你的特殊情况下,你的virtual
方法返回一个基本类型,它没有协方差,因为它不能被放在一个普通的类型,如c#中的System.Object
。
为了完成协方差,你需要定义一个类作为所有返回类型的基类。
Within the type system of a programming language, covariance and contravariance refers to the
ordering of types from narrower to wider and their interchangeability or equivalence in certain
situations (such as parameters, generics, and return types).
covariant: converting from a specialized type (Cats) to a more general type (Animals):
Every cat is an animal.
这是文章的链接
只有在用指向派生类的指针/引用替换指向基类的指针/引用时才允许更改虚函数的返回类型,因为一个可以安全地转换为另一个。虽然enum类型和int
是兼容的,但它们在技术上并不相关。只要在任何地方使用int
,因为枚举名称只是一个装饰,根本不影响任何东西。
你的设计需要修正,但是关于技术你可以做
class Derived1
: public Base
{
public:
enum D1
{
d1_1 = 0,
d1_2 = 60,
...
d1_100
};
D1 GetD1Data () const;
int GetData() const override { return GetD1Data(); }
};
根据c++ 11 ISO 10.3/7:
重写函数的返回类型要么与被重写函数的返回类型相同,要么与函数的类协变。如果函数D::f覆盖函数B::f,则满足以下条件的函数的返回类型是协变的:
- 都是类指针,都是类的左值引用,或者都是类的右值引用
—B::f返回类型中的类与D::f返回类型中的类是同一类,或者是D::f返回类型中类的明确且可访问的直接或间接基类
—两个指针或引用具有相同的cv-限定符,并且D::f返回类型中的类类型与B::f返回类型中的类类型具有相同或更少的cv-限定符。
协方差只允许用于指针、左值/右值引用。我猜您不希望通过引用或指针返回enum。
但是,如果您接受静态线程本地缓冲区,则可以使用以下方法:
现场演示
class EnumA
{
int value_;
public:
explicit EnumA(int v)
: value_{v}
{}
int value() const
{
return value_;
}
};
struct EnumB: EnumA
{
enum EnumB_T{one,two};
explicit EnumB(EnumB_T v)
: EnumA{v}
{}
EnumB_T value() const
{
return EnumB_T(EnumA::value());
}
};
struct A
{
virtual const EnumA &func() const
{
static thread_local EnumA result{0};
return result = EnumA{1};
}
};
struct B: A
{
virtual const EnumB &func() const override
{
static thread_local EnumB result{EnumB::one};
return result = EnumB{EnumB::two};
}
};
- 如何获取std::result_of函数的返回类型
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 模板返回类型函数如何在C++中工作
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 在引用或指针返回类型函数上输入
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 我可以在c++中重写字符串返回类型函数吗?