返回类型与被覆盖的虚函数"MediaFactory :: FMediaDevice"的返回类型"MediaDevice*"不相同,也不协变

Return type is not identical to nor covariant with return type "MediaDevice*" of overridden virtual function "MediaFactory :: FMediaDevice"

本文关键字:返回类型 覆盖 函数 MediaFactory MediaDevice FMediaDevice      更新时间:2023-10-16

我有以下抽象工厂:

#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(){}
   };

我得到以下错误

返回类型与重写的虚拟函数"MediaFactory::FMediaDevice"的返回类型"MediaDevice*"不相同,也不协变

重要的是,在visula studio中,我在MedDevFactory类中的声明MediaDevice*FMediaDevice(int type){中的FMediaDevice下有红线。我返回什么并不重要。我可以返回0,但仍然会得到错误。

为什么?

从错误消息来看,JVCCdPlayerJVCVcrPlayer(或两者)似乎不是从MediaDevice派生的。是这样吗?

两者都必须从MediaDevice派生。确保你的定义看起来像这样:

class JVCCdPlayer : public MediaDevice
{
};
class JVCVcrPlayer : public MediaDevice
{
};

或者在层次结构中的某个位置,MediaDevice应该存在。


MediaDevice具有类型为pair<string,string>的成员数据DeviceName,但您还没有包括在其中定义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,因为您是从派生类JVCVcrPlayerJVCCdPlayer访问它的。

MediaDevice可能不是JVCCdPlayer或JVCVcrPlayer的母公司。

还要注意的是,函数JVCMedDevFactory::FMediaDevice并不总是保证返回值-您应该在switch语句中有一个默认情况,或者在函数底部有一个缺省返回。

经过以下更改后,Visual Studio 2010编译了您的代码(尽管我将所有代码都放在一个源文件中)。

  1. 包括所有要求的标题
  2. 使MediaDevice::DeviceName成为受保护(非私有)成员,以便玩家类的构造函数可以访问它
  3. type_e定义为枚举
  4. MediaDevice成员函数的声明中删除"纯虚拟"=0说明符,并添加`MediaDevice::getName()的明显定义

在实际代码中,最后一步应该将纯虚拟函数的重写定义添加到播放器类中,但我懒得写

我需要说的是,在任何阶段我都没有看到"返回类型与诊断不相同,也不协变"。

希望这能有所帮助。