C++:不能将字段声明为抽象类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4296276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:03:48  来源:igfitidea点击:

C++ : Cannot declare field to be of abstract type

c++abstract-class

提问by user522767

I get this error on compile -> cannot declare field M1::sc to be of abstract type I1 because the following virtual functions are pure within I1. Please help.

我在编译时遇到此错误 -> 无法将字段 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);
    };

Complete code can be found on http://pastebin.com/PFrMTJuF.

完整代码可以在http://pastebin.com/PFrMTJuF上找到。

采纳答案by Frédéric Hamidi

Abstract classescan't be instantiated, but you're asking the compiler to do just that by embedding an instance of I1into every instance of M1.

抽象类不能被实例化,但是您要求编译器通过将 的实例嵌入I1到 的每个实例中来做到这一点M1

You can work around that by slightly changing your design and embedding a pointer(or a smart pointer, if you can use those) to an instance of I1instead:

您可以通过稍微更改您的设计并将指针(或智能指针,如果您可以使用它们)嵌入到以下实例I1来解决此问题:

class M1 : public G1
{
protected:
    I1 *sc;
public:
    M1(I1 *sc_) {
        sc = sc_;
    }
    void foo() {
        int dir = 4;
        sc->a(dir);
    }
};

EDIT:After reading your code, I think that the simplest and cleanest way to solve your problem is to pass the current room to the Execute()method of your command, e.g. something like:

编辑:阅读您的代码后,我认为解决您的问题的最简单和最干净的方法是将当前房间传递给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;
    }
}

回答by Konrad Rudolph

I1is an abstract class because it has purely virtual functions (= functions without a definition).

I1是一个抽象类,因为它具有纯虚函数(= 没有定义的函数)。

You cannot create instances of abstract classes (because how would they work?!), therefore a declaration such as I1 adoesn't work.

您不能创建抽象类的实例(因为它们将如何工作?!),因此诸如此类的声明I1 a不起作用。

After your edit to the question it seems as though I1shouldn't be an abstract class, since you provided definitions for the methods. If that's the case, just remove the = 0after your method declarations to make the code work.

在对问题进行编辑后,似乎I1不应该是抽象类,因为您提供了方法的定义。如果是这种情况,只需删除= 0方法声明之后的后面即可使代码工作。

回答by Mihran Hovsepyan

You can't create instance to abstract class (the class which has one or more pure virtual functions). Also there is another problem. What do you want compiler to do when you call function sc.a(dir)in class declaration? The line dir = 4is also incorrect, only static const members of class can be initializated in class declaretion.

您不能为抽象类(具有一个或多个纯虚函数的类)创建实例。另外还有一个问题。当您sc.a(dir)在类声明中调用函数时,您希望编译器做什么?该行dir = 4也不正确,只能在类声明中初始化类的静态常量成员。