我有以下抽象工厂:
#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并仍然得到错误。
为什么?
答案 0 :(得分:2)
从错误消息中,似乎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
和{{1}访问它}。
答案 1 :(得分:0)
MediaDevice可能不是JVCCdPlayer或JVCVcrPlayer的父级。
另请注意,函数JVCMedDevFactory :: FMediaDevice并不总是保证返回一个值 - 您应该在switch语句中有一个默认大小写,或者在函数底部有一个默认返回值。
答案 2 :(得分:0)
完成以下更改后,Visual Studio 2010会编译您的代码(尽管我将其全部放在一个源文件中)。
MediaDevice::DeviceName
成为受保护(非私有)成员,以便玩家类的构造者可以访问它; type_e
定义为枚举; =0
成员函数的声明中删除“纯虚拟”MediaDevice
说明符,并为`MediaDevice :: getName()添加一个明显的定义。在实际代码中,最后一步应该是将纯虚函数的重写定义添加到播放器类中,但我懒得写它。
我需要说的是,在任何阶段我都没有看到“返回类型与”诊断不相同或协变。
希望这有帮助。