返回类型是否会影响函数覆盖? (据我所知,返回typde不是函数/方法签名的一部分)
在基类中,我有一个函数,它不获取参数,返回int
并且是纯虚拟的。在每个派生类中,我为返回类型定义了一个枚举。在派生类中重写了该函数,即它具有相同的签名但行为不同。
问题是:覆盖和返回类型的合法性是不是函数覆盖的一部分吗?
代码示例:
class Base
{
public:
typedef int ret;
virtual ret method() = 0;
};
class Der1
{
public:
enum ret1{
ret1_0,
ret1_1
};
ret1 method() { return ret1_1;}
};
class Der1
{
public:
enum ret2{
ret2_0,
ret2_1
};
ret1 method() { return ret2_0;}
};
答案 0 :(得分:4)
您可以使用不同的返回类型覆盖函数,但只允许协变返回类型。
Function Overriding意味着将在运行时调用Base类方法或Derived类方法,具体取决于指针指向的实际对象。
它意味着:
即:可以通过调用Derived类方法替换可以调用Base类方法的每个地方,而无需更改调用代码。
为了实现这一点,唯一可行的方法是限制覆盖虚拟方法的返回类型返回与Base类相同的类型或从中派生的类型(共变量返回类型),因此标准强制执行这种情况。
如果没有这个条件,现有代码将通过添加新功能(新的重写函数)而中断。
答案 1 :(得分:4)
简短的回答:不,这是不允许的,或者更好的是它不会覆盖但是覆盖,即你没有覆盖Base::method()
,而是创建一个具有相同名称的新方法。大多数编译器会警告你。使用示例代码,但假设Base::method
不是纯虚拟,请考虑以下事项:
void callMethod(Base const& b)
{
auto a1 = b.method(); //what should the type of a1 be? -> it's int. Every time.
std::cout << a1 << '\n';
}
int main()
{
Der1 d1;
auto a2 = d1.method(); //a2 is ret1_1 of type ret1
callMethod(d1); //calls Base::method and prints that int, not Der1::method
}
你是对的,返回类型不是函数签名的一部分。但是当覆盖虚函数时,签名并不重要。 §10.3,7明确指出:
覆盖函数的返回类型应与...相同 被覆盖函数的返回类型或协变与 功能的类。如果函数
D::f
覆盖函数B::f
,函数的返回类型如果满足则是协变的 以下标准:- 两者都是指向类的指针,两者都是 左值对类的引用,或两者都是对它的右值引用 类
- 返回类型
B::f
中的类与 返回类型为D::f
的类,或者是明确的类 返回中类的可访问直接或间接基类 类型D::f
- 指针或引用都有相同的含义 cv-qualification和
D::f
的返回类型中的类类型有 与类类型相同的cv资格或更少的cv资格 在返回类型B::f
。
答案 2 :(得分:1)
你拥有的不是覆盖。
c ++支持原始指针和原始引用的协变返回类型。
但就是这样。
答案 3 :(得分:1)
我们不应该通过覆盖它来改变基类中函数的返回类型。不推荐通过隐藏基本成员来改变返回类型,因为它会产生一些奇怪的东西,不能以多态方式使用。