C++ 返回类型与返回类型不相同,也不共变;MediaDevice*”;“被重写的虚拟函数的定义”;MediaFactory::FMediaDevice“;

C++ 返回类型与返回类型不相同,也不共变;MediaDevice*”;“被重写的虚拟函数的定义”;MediaFactory::FMediaDevice“;,c++,factory,abstract,C++,Factory,Abstract,我有以下抽象工厂: #include "MediaDevice.h" class MediaFactory { public: MediaFactory(); virtual ~MediaFactory(); virtual MediaDevice * FMediaDevice (int type) = 0; }; 以下是从抽象工厂继承下来的工厂: #include "MediaFactory.h" class JVCMedDevFactory : public

我有以下抽象工厂:

#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;
};
#包括
#包括
使用名称空间std;
类媒体设备{
公众:
媒体设备();
虚拟媒体设备();
虚拟void Start()=0;
虚空停止()=0;
虚空转发()=0;
虚空倒带()=0;
虚拟对getName()常量=0;
受保护的:
配对设备名称;
};
我是这样定义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.h”
#包括
使用名称空间std;
JVCDPlayer类:公共媒体设备{
公众:
JVCDPlayer(){
DeviceName.first=“JVC”;
DeviceName.second=“CD”;
}
无效开始(){

从错误消息中可以看出,
JVCDPlayer
JVCPlayer
(或两者)似乎不是从
MediaDevice
派生的。是这样吗

您必须从
MediaDevice
中派生这两种定义。请确保您的定义如下所示:

class JVCCdPlayer : public MediaDevice
{
};

class JVCVcrPlayer : public MediaDevice
{
};
或者在层次结构中的某个位置,应该存在
MediaDevice


MediaDevice
具有成员数据
DeviceName
,类型为
pair
,但您尚未包含定义了
pair
的标头。因此,请包含
。同样,请确保已包含所有必要的标头

此外,我不会在头文件中使用命名空间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
您是否在派生类中定义了它?(虽然错误没有说明这是问题所在,但仍然要确保这一点)


此外,成员数据
DeviceName
声明为
private
,需要对其进行
保护
,因为您是从派生类
JVCpLayer
JVCdPlayer
访问它的,MediaDevice可能不是JVCdPlayer或JVCpLayer的父级


还请注意,函数JVCMEDEVFactory::FMediaDevice并不总是保证返回值-您应该在switch语句中有一个默认大小写,或者在函数的底部有一个默认返回值。

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

  • 包括所有必需的标题
  • 使
    MediaDevice::DeviceName
    成为受保护的(非私有)成员,以便播放器类的构造函数可以访问它
  • type_e
    定义为枚举
  • MediaDevice
    成员函数的声明中删除“纯虚拟”
    =0
    说明符,并为`MediaDevice::getName()添加明显的定义
  • 在实际代码中,最后一步应该将纯虚拟函数的重写定义添加到播放器类中,但我懒得编写它

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


    希望这有帮助。

    我们需要查看
    JVCDPlayer
    JVCRPLAYER
    的定义。错误似乎表明
    MediaDevice
    正在解析为
    MediaFactory
    JVCMedevFactory
    的定义之间的两种不同类型。您是在名称空间中使用前向声明还是在某些名称空间中使用前向声明可能导致这种情况发生的事情?我已经添加了JVCDPlayer和JVCVcrPlayer@sera:同时发布
    “MediaDevice.h”
    @Nawaz:它已经存在。在“Media device is:”下。谢谢!从visual studio中,我可以看到问题在于函数MediaDevice*FMediaDevice(int类型)的声明。它用红线标记为FMediaDevice。我返回的内容对他来说并不重要。我输入了retrun 0,但仍然看到了错误。但是JVCDPlayer和JVCPlayer也从MediaDevice中删除。这意味着“MediaDevice应该存在”是什么意思?非常感谢!@sera:为什么
    pair
    不需要标题?另外,我猜你的程序出现了其他错误。你发布了所有错误消息吗?@Nawaz:我猜已经在Visual Studio中隐式包含了
    。@Nawaz:对不起,我现在检查了,确实看到了另一个错误:它在下面用红线标记了-返回新的JVCDPlayer();-并说不允许使用抽象类类型JVCDPlayer的对象。我想这是因为我今天更改了JVCDPlayer和JVCRPLAYER类,并从中删除了纯虚拟函数的实现。但即使我不使用这些类,也仍然如此。只返回0。我提到的第一个错误仍然存在。我只使用了#包括为pair@sera:是的。我是对的。这是因为您没有在派生类中定义
    getName
    纯虚拟函数。请记住,纯虚拟函数需要在派生类中实现!非常感谢您的帮助,正如我所说,我尝试只留下一行-在imp中返回0函数JVCMedDevFactory::FMediaDevice的实现仍然存在错误我想我对“包括所有必需的头”有问题.你能告诉我你是怎么放标题的吗?Thanks@sera:我需要为
    std::cout
    添加
    #include
    ,我还为
    std::pair
    添加了
    #include
    ,尽管它是通过其他一些VC标题隐式包含的。谢谢你的帮助。我按照Nawaz的说明解决了问题。但我相信伊芙说你的解决方案也很好。
    virtual pair <string,string> getName () const = 0;