返回类型与重写虚拟函数“MediaFactory :: FMediaDevice”的返回类型“MediaDevice *”不相同或协变

时间:2011-05-28 23:28:30

标签: c++ factory abstract

我有以下抽象工厂:

#include  "MediaDevice.h"

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

以及继承自抽象facotry的工厂:

#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工作室我在声明MediaDevice * FMediaDevice(int type){在MedDevFactory类中的声明中在FMediaDevice下有红线是重要的。我回来的并不重要。我可以返回0并仍然得到错误。

为什么?

3 个答案:

答案 0 :(得分:2)

从错误消息中,似乎JVCCdPlayerJVCVcrPlayer(或两者)都不是从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和{{1}访问它}。

答案 1 :(得分:0)

MediaDevice可能不是JVCCdPlayer或JVCVcrPlayer的父级。

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

答案 2 :(得分:0)

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

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

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

    希望这有帮助。