我在编译时遇到此错误 - >不能将字段M1 :: sc声明为抽象类型I1,因为以下虚函数在I1中是纯粹的。请帮忙。
class I1
{
public:
virtual void a(int dir) = 0;
virtual void b() = 0;
virtual void c() = 0;
void a(int dir) {
....
}
void b() {
....
}
void c() {
....
}
};
class I2 : public I1
{
public:
void a(int dir) {
....
}
void b() {
....
}
void c() {
....
}
};
class M1 : public G1
{
protected:
I1 sc;
public:
int dir = 4;
sc.a(dir);
};
可以在http://pastebin.com/PFrMTJuF上找到完整的代码。
答案 0 :(得分:15)
Abstract classes无法实例化,但您要求编译器通过在I1
的每个实例中嵌入M1
的实例来实现这一目标。
你可以通过稍微改变你的设计并将指针(或智能指针,如果你可以使用它们)嵌入到I1
的实例来解决这个问题:
class M1 : public G1
{
protected:
I1 *sc;
public:
M1(I1 *sc_) {
sc = sc_;
}
void foo() {
int dir = 4;
sc->a(dir);
}
};
编辑:在阅读完代码后,我认为解决问题的最简单,最简洁的方法是将当前会议室传递给您的Execute()
方法,例如类似的东西:
class ICommand
{
public:
virtual ~ICommand()
{
}
virtual void Execute(Room *room) = 0;
};
class MoveCommand : public GameCommand
{
public:
MoveCommand()
{
}
void Execute(Room *room)
{
// Do something with `room`...
}
};
void Game::HandleInput()
{
// Read command from user and generate a command object from it.
ICommand *pCommand = ParseCommand(Input::ReadCommand());
if (pCommand) {
pCommand->Execute(GetCurrentRoom()); // Pass current room to command.
delete pCommand;
}
}
答案 1 :(得分:7)
I1
是一个抽象类,因为它具有纯虚函数(=没有定义的函数)。
你不能创建抽象类的实例(因为它们如何工作?!),因此诸如I1 a
之类的声明不起作用。
在您对问题进行编辑之后,似乎I1
不应该是抽象类,因为您提供了方法的定义。如果是这种情况,只需在方法声明后删除= 0
即可使代码正常工作。
答案 2 :(得分:1)
您无法为抽象类(具有一个或多个纯虚函数的类)创建实例。
还有另一个问题。在类声明中调用函数sc.a(dir)
时,您希望编译器做什么?行dir = 4
也是不正确的,只有类的静态const成员可以在类声明中初始化。