函数覆盖不同的返回类型

时间:2013-02-25 09:55:08

标签: c++ override return-type

返回类型是否会影响函数覆盖? (据我所知,返回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;}
};

4 个答案:

答案 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)

我们不应该通过覆盖它来改变基类中函数的返回类型。不推荐通过隐藏基本成员来改变返回类型,因为它会产生一些奇怪的东西,不能以多态方式使用。