Переопределение виртуальных функций с различными типами возвращаемых данных вызывает ошибку с частным наследованием


В следующем коде я получил следующие ошибки компиляции:

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 3

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]
  1. Возвращаемый тип переопределяющей функции должен быть либо идентичен возвращаемому типу переопределяемой функции, либо ковариантен классам функций. Если функция 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.

Вы должны изменить все fun() s, чтобы вернуть Base1.