Тип возврата не идентичен и не является ковариантным с типом возврата "MediaDevice *" переопределенной виртуальной функции "MediaFactory :: FMediaDevice" - PullRequest
3 голосов
/ 29 мая 2011

У меня есть следующая абстрактная фабрика:

#include  "MediaDevice.h"

class MediaFactory {
public:
    MediaFactory();
    virtual ~MediaFactory();
    virtual  MediaDevice * FMediaDevice (int type) = 0;
};

и следующая фабрика, которая наследуется от абстрактной фасотрии:

#include "MediaFactory.h"
class JVCMedDevFactory : public MediaFactory {
public:
    MediaDevice* FMediaDevice (int type) {
        switch ((type_e)type) {
            case CDPlayer_e:
            return new JVCCdPlayer() ;
            case DVDPlayer_e:
                return new JVCVcrPlayer() ;
        }
} 
}; 

Медиа-устройство:

#include <string>
#include <utility>
using namespace std;
class MediaDevice {
 public:
MediaDevice();
    virtual ~MediaDevice();
virtual void Start () = 0 ;
virtual void Stop () = 0 ;
    virtual void Forward () = 0 ;
virtual void Rewind () = 0 ;
virtual pair <string,string> getName () const = 0;
protected:
pair <string,string> DeviceName;
};

ЭтоВот как я определяю проигрыватели JVC:

#include "MediaDevice.h"
#include <iostream>
using namespace std;   
class JVCCdPlayer : public MediaDevice {
public:
    JVCCdPlayer(){
            DeviceName.first = "JVC";
            DeviceName.second = "CD";
    }
    void Start (){
    cout << "Playing " << this->getName().first << "," << this->getName().second <<     endl;
}
    void Stop (){
    cout << "Stopped " << this->getName().first << "," << this->getName().second     <<endl;
    }
    void Forward (){
    cout << "Rewind " << this->getName().first << "," << this->getName().second <<endl;
}
void     Rewind (){
    cout << "Forward " << this->getName().first << "," <<this->getName().second <<endl;
    }
    pair <string,string> getName () const{
    return DeviceName;
    }
    ~JVCCdPlayer(){}
   };

И я получаю следующую ошибку

Тип возврата не идентичен и не является ковариантным с типом возврата "MediaDevice *" переопределенной виртуальной функции "MediaFactory:: FMediaDevice "

Важно, чтобы в visula studio у меня была красная линия под FMediaDevice в объявлении MediaDevice * FMediaDevice (int type) {в классе MedDevFactory.И не важно, что я вернусь.Я могу вернуть 0 и все равно получить ошибку.

Почему?

Ответы [ 3 ]

2 голосов
/ 29 мая 2011

Из сообщения об ошибке кажется, что JVCCdPlayer или JVCVcrPlayer (или оба) не являются производными от MediaDevice. Это так?

Вы должны получить оба из MediaDevice. Убедитесь, что ваши определения выглядят так:

class JVCCdPlayer : public MediaDevice
{
};

class JVCVcrPlayer : public MediaDevice
{
};

Или где-то в иерархии, MediaDevice должен присутствовать.


Класс MediaDevice содержит данные члена DeviceName типа pair<string,string>, но вы не включили заголовок, в котором определен pair. Так что включайте <utility>. Точно так же убедитесь, что вы включили все необходимые заголовки.

Кроме того, я бы не стал писать using namespace std в заголовочном файле. Поэтому я бы переписал MediaDevice.h как:

#ifndef MEDIA_DEVICE_H
#define MEDIA_DEVICE_H

#include <string>
#include <utility>

class MediaDevice 
{
  public:
     MediaDevice();
     virtual ~MediaDevice();
     virtual void Start () = 0 ;
     virtual void Stop () = 0 ;
     virtual void Forward () = 0 ;
     virtual void Rewind () = 0 ;
     virtual std::pair<std::string,std::string> getName () const = 0;
  private:
     std::pair<std::string,std::string> DeviceName;
};

#endif

То есть я бы назвал каждое имя std:: вместо using namespace std.

Кстати, я не вижу определения следующей чисто виртуальной функции:

virtual pair <string,string> getName () const = 0;

Вы определили это в производных классах? (хотя ошибка не говорит о том, что это проблема, но все равно убедитесь в этом).

Кроме того, данные члена DeviceName объявлены как private, который должен быть protected, поскольку вы обращаетесь к нему из производных классов JVCVcrPlayer и JVCCdPlayer.

0 голосов
/ 29 мая 2011

После следующих изменений Visual Studio 2010 скомпилировал ваш код (хотя я поместил все это в один исходный файл).

  1. Включая все необходимые заголовки;
  2. Создание MediaDevice::DeviceName защищенного (не частного) члена, чтобы к нему могли обращаться конструкторы классов игроков;
  3. Определение type_e в качестве перечисления;
  4. Удаление «чисто виртуального» спецификатора =0 из объявлений MediaDevice функций-членов и добавление очевидного определения для MediaDevice :: getName ().

В реальном коде последний шаг должен вместо этого добавить в классы проигрывателя переопределяющие определения чисто виртуальных функций, но мне было лень писать это.

Я должен сказать, что ни на одной стадии я не видел диагностику «Тип возврата не идентичен и не ковариантен с».

Надеюсь, это поможет.

0 голосов
/ 29 мая 2011

MediaDevice, вероятно, не является родителем JVCCdPlayer или JVCVcrPlayer.

Также обратите внимание, что функция JVCMedDevFactory :: FMediaDevice не всегда гарантирует возврат значения - у вас должен быть регистр по умолчанию в выражении switch или возврат по умолчанию в нижней части функции.

...