使用不同的返回类型覆盖虚函数会引发私有继承的错误

时间:2014-10-14 07:18:01

标签: c++ return-type method-overriding

在下面的代码中,我得到了以下编译错误:

1>c:\users\mittamani\desktop\06-10\over_riding_test\over_riding_test\over_riding_test.cpp(33) : error C2555: '_D1::fun': overriding virtual function return type differs and is not covariant from 'Base2::fun'
1>        c:\users\mittamani\desktop\06-10\over_riding_test\over_riding_test\over_riding_test.cpp(28) : see declaration of 'Base2::fun'
1>        'Base1' : base class is not accessible
1>c:\users\mittamani\desktop\06-10\over_riding_test\over_riding_test\over_riding_test.cpp(37) : error C2555: '_D2::fun': overriding virtual function return type differs and is not covariant from 'Base2::fun'
1>        c:\users\mittamani\desktop\06-10\over_riding_test\over_riding_test\over_riding_test.cpp(28) : see declaration of 'Base2::fun'
1>        'Base1' : base class is not accessible
1>Build log was saved at "file://c:\Users\mittamani\Desktop\06-10\Over_riding_Test\Over_riding_Test\Debug\BuildLog.htm"
1>Over_riding_Test - 2 error(s), 0 warning(s)

以下是代码:

class Base1{
public:
    Base1(){}
    virtual ~Base1(){}
};

class D1:Base1{

};

class D2:Base1{

};

class Base2{
public:
    Base2(){}
    virtual ~Base2(){}
    virtual Base1 * fun() = 0;
};

class _D1:Base2{
public:
    D1* fun(){}
};

class _D2:Base2{
public:
    D2* fun(){}
};

顺便说一下,我对C ++更新鲜了..请帮忙..提前谢谢..

3 个答案:

答案 0 :(得分:4)

假设您尝试使用covariance of return types,您的尝试是有效的,除了类型必须使用公共继承这一事实:

class D1:public Base1{
//       ~~~~~^

};

class D2:public Base1{
//       ~~~~~^    
};

class _D1 : Base2{
public:
    D1* fun(){} // ok now, D1 inherits publicly from Base1
};

class _D2 : Base2{
public:
    D2* fun(){} // ok now, D2 inherits publicly from Base1
};

就像你不能将D2*强制转换为Base1*,除非你使用公共继承,这同样适用于此。

DEMO


或者,您必须使这些类成为朋友,以便他们可以访问到私有基类:

class _D1;
class _D2;

class D1 : Base1{
    friend class _D1;
};

class D2 : Base1{
    friend class _D2;
};

C ++标准参考:

  

§10.3虚函数[class.virtual]

     
      
  1. 重写函数的返回类型应与重写函数的返回类型相同或与函数类的协变相同。如果函数D::f覆盖函数B::f,则函数的返回类型如果满足以下条件则是协变的:

         

    - 两者都是指向类的指针,都是对类的左值引用,或者两者都是对类的右值引用

         

    - 返回类型B::f中的类与返回类型D::f中的类相同,或者是明确的且可访问直接或间接的类返回类型为D::f

    的类的基类      

    - 指针或引用都具有相同的cv限定,并且返回类型D::f中的类类型具有与返回类型{中的类类型相同的cv-qualification或更少cv-qualification {1}}。

  2.   

答案 1 :(得分:2)

重写函数的返回类型应与重写函数的返回类型相同或与函数类的协变相同。如果函数D :: f重写函数B :: f,则函数的返回类型如果满足以下条件则是协变的:

- 指向类或对类的引用的指针 -B :: f的返回类型中的类与D :: f的返回类型中的类相同,或者是D :: f的返回类型中类的明确的直接或间接基类并且可以在D中访问 -both指针或引用具有相同的cv限定,并且返回类型D :: f中的类类型具有与b :: f的返回类型中的类类型相同的cv-qualification或更少的cv-qualification。

答案 2 :(得分:-2)

您必须更改所有fun()以返回Base1