Переопределение виртуальных функций с различными типами возвращаемых данных вызывает ошибку с частным наследованием
В следующем коде я получил следующие ошибки компиляции:
1>c:usersmittamanidesktop6-10over_riding_testover_riding_testover_riding_test.cpp(33) : error C2555: '_D1::fun': overriding virtual function return type differs and is not covariant from 'Base2::fun'
1> c:usersmittamanidesktop6-10over_riding_testover_riding_testover_riding_test.cpp(28) : see declaration of 'Base2::fun'
1> 'Base1' : base class is not accessible
1>c:usersmittamanidesktop6-10over_riding_testover_riding_testover_riding_test.cpp(37) : error C2555: '_D2::fun': overriding virtual function return type differs and is not covariant from 'Base2::fun'
1> c:usersmittamanidesktop6-10over_riding_testover_riding_testover_riding_test.cpp(28) : see declaration of 'Base2::fun'
1> 'Base1' : base class is not accessible
1>Build log was saved at "file://c:UsersmittamaniDesktop6-10Over_riding_TestOver_riding_TestDebugBuildLog.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 ответа:
Предполагая, что вы пытаетесь использовать ковариация типов возвращаемых данных, ваши попытки допустимы, за исключением того, что типы должны использовать открытое наследование:
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*
, Если вы не используете публичное наследование, то же самое применимо и здесь.Демо-версия
В качестве альтернативы, вы должны были бы сделать эти классы друзьями, чтобы они имели доступ к частной базе класс:
class _D1; class _D2; class D1 : Base1{ friend class _D1; }; class D2 : Base1{ friend class _D2; };
Стандартная ссылка на C++:
§ 10.3 виртуальные функции[class.virtual]
- Возвращаемый тип переопределяющей функции должен быть либо идентичен возвращаемому типу переопределяемой функции, либо ковариантен классам функций. Если функция
D::f
переопределяет функциюB::f
, возвращаемые типы функций являются ковариантными, если они удовлетворяют следующим критериям:- оба являются указателями на классы, оба являются ссылки lvalue на классы, или оба являются ссылками rvalue на классы
- класс в возвращаемом типе
B::f
является тем же классом, что и класс в возвращаемом типеD::f
, или является однозначным и доступным прямым или косвенным базовым классом класса в возвращаемом типеD::f
- оба указателя или ссылки имеют одинаковую cv-квалификацию, а тип класса в возвращаемом типе
D::f
имеет ту же CV-квалификацию, что и CV-квалификация, или меньше, чем тип класса в возвращаемом типеB::f
.
Возвращаемый тип переопределяющей функции должен быть либо идентичен возвращаемому типу переопределяемой функции, либо ковариантен классам функций. Если функция D:: f переопределяет функцию B:: f, возвращаемые типы функций являются ковариантными, если они удовлетворяют следующим критериям:
- оба являются указателями на классы или ссылками на классы
- класс в возвращаемом типе B:: f является тем же классом, что и класс в возвращаемом типе D:: f or, является однозначным прямым или косвенный базовый класс класса в возвращаемом типе D:: f и доступен в D
- оба указателя или ссылки имеют одинаковую квалификацию cv, а тип класса в возвращаемом типе D:: f имеет ту же квалификацию cv, что и тип класса в возвращаемом типе B:: f.