协变虚函数返回类型问题

时间:2011-02-22 09:18:45

标签: c++ inheritance virtual covariance

我有以下代码:

#include <iostream>
using namespace std;

class Child1
{
    int i;
};

class Child2 : public Child1
{
    int j;
};

class Base1
{

public:

    virtual Child1& getChildren()
    {
        cout << "Children1" << endl;
        return children;
    }

private:

    Child1 children;
};

class Base2 : public Base1
{

public:

    virtual Child2& getChildren()
    {
        cout << "Children2" << endl;
        return children;
    }

private:

    Child2 children;
};

这段代码编译得很好但是当我在getChildren()Base1中的一个或两个中将Base2的返回类型从引用类型更改为对象类型时(例如virtual Child2 getChildren())在Visual Studio 2010上收到以下错误:

error C2555: 'Base2::getChildren': overriding virtual function return type differs and is not covariant from 'Base1::getChildren'

我想知道为什么我在使用引用时会出现此错误,否则会得到此错误。这是VS2010中的错误吗?因为C ++标准(根据微软网站上的this页面)说的是:重写函数的返回类型应该与被覆盖函数的返回类型相同,或者与类的属性相同。函数。 B :: f的返回类型中的类与D :: f的返回类型中的类是同一个类,或者是类的明确的直接或间接基类在D :: f的返回类型中,可以在D。

中访问

P.S。我目前无法访问该标准,因此无法验证上述报价。

3 个答案:

答案 0 :(得分:15)

你错过了他们引用的另一部分:“如果函数D :: f覆盖函数B :: f,如果它们满足以下条件,函数的返回类型是协变的:(1)两者都是指针到类或引用到类“

答案 1 :(得分:4)

它们必须是引用或指针,而不是具体的类。这些要求可以在您的MS报价中的“可变性”规定内幸福地生活。第二部分讲述了“返回类型中的类” - 请注意他们避免“返回类”的关注,因为它是指针或类引用返回类型的类组件。

考虑协方差是什么:你要找回一个对象,为基类编写的一些现有代码可能希望处理它,但是通过虚拟调度最终得到你的一个对象。如果它们的大小不同,那么如何存储对象?这个混乱被间接所包围......你可以决定它们的位置(一些缓冲区,共享内存,堆),协变返回类型是指针或引用。

答案 2 :(得分:0)

如果要将字符串转换(如std :: string)更改为std :: wstring或虚函数的任何字符串转换,则需要更改该虚拟函数的超类,其中实际声明了该虚函数。您需要更改使用函数的每个位置,以便更改字符串转换。

在我的情况下,发生了希望它会帮助一些人......