【问题标题】:cannot allocate an object of abstract type无法分配抽象类型的对象
【发布时间】:2015-01-02 15:41:58
【问题描述】:

在下面的代码 sn-p 中,我在添加纯虚函数 createImage 时遇到错误 GUIFactory 类。

错误:无法分配抽象类型“工厂”的对象

这里的 Factory 不是抽象类,所以理想情况下它应该是可实例化的。除此之外,如果删除此功能并仅添加纯虚拟 createButton,则我不会收到此错误,这似乎是有效的行为。

代码:

#include <iostream>
#include<string.h>
using namespace std;
class Button {
public:
    virtual void paint() = 0;
};

class Image {
public:
        virtual void paint() = 0;
};

class OSXButton: public Button {
public:
    void paint() {
        std::cout << "OSX button \n";
    }
};

class WindowsButton: public Button  {
public:
    void paint() {
        std::cout << "Windows button \n";
    }
};

class iPhoneButton: public Button {
public:
    void paint() {
        std::cout << "iPhone button \n";
    }
};

class OSXImage: public Image {
public:
        void paint() {
                std::cout << "OSX button \n";
        }
};

class WindowsImage: public Image  {
public:
        void paint() {
                std::cout << "Windows button \n";
        }
};

class iPhoneImage: public Image {
public:
        void paint() {
                std::cout << "iPhone button \n";
        }
};


class GUIFactory {
public:
    virtual Button *createButton(const char *) = 0;
       virtual Image *createImage(const char *) = 0;//If this function is commented code works fine. 
};

class Factory: public GUIFactory {
public:
    Button *createButton(const char *type) {
        if(strcmp(type,"Windows") == 0) {
            return new WindowsButton;
        }
        else if(strcmp(type,"OSX") == 0) {
            return new OSXButton;
        }

                else if(strcmp(type,"iPhone") == 0) {
                        return new iPhoneButton;
                }
                else
                {

              return NULL;
                }




    }

#if 0
Image *createImage(const char *type) {
                if(strcmp(type,"Windows") == 0) {
                        return new WindowsImage;
                }
                else if(strcmp(type,"OSX") == 0) {
                        return new OSXImage;
                }

                else if(strcmp(type,"iPhone") == 0) {
                        return new iPhoneImage;
                }
                else
                {

              return NULL;
                }




        }

#endif


};

int main()
{
    GUIFactory* guiFactory;
    Button *btn;
        Image *img;

    guiFactory = new Factory;

    btn = guiFactory->createButton("OSX");
        if(btn!=NULL)
        {
    btn -> paint();
        }

    btn = guiFactory->createButton("Windows");
        if(btn!=NULL)
        {
        btn -> paint();
        }

        btn = guiFactory->createButton("iPhone");
        if(btn!=NULL)
        {
        btn-> paint();
        }

        #if 0
        img = guiFactory->createImage("OSX");
        if(img!=NULL)
        {
        img -> paint();
        }

        img = guiFactory->createImage("Windows");
        if(img!=NULL)
        {
        img -> paint();
        }

        img = guiFactory->createImage("iPhone");
        if(img!=NULL)
        {
        img -> paint();
        }




        //btn -> paint();
        #endif
        delete guiFactory;
       // delete Button;
    return 0;
}

【问题讨论】:

  • 是因为#if 0 吗?无论如何,对于一个简单的错误,这似乎有很多代码。也许这就是反对票的原因?
  • 这是故意让我的观点清楚的。如果我给出功能声明,那么定义是显而易见的,但我已经发表了相同的评论以揭示这个错误:) 如果没有正确回答问题,则不接受投票:)。我已经非常清楚地表明了我的观点,“这里的工厂不是一个抽象类,所以理想情况下它应该是可实例化的。除此之外,如果删除了这个函数并且只添加了纯虚拟 createButton,那么我不会收到这个错误,这似乎是有效的行为”
  • 好吧,您可能应该编辑您的问题,使其更加清晰(“通过插入 if 0... 删除?”),因为似乎我不是唯一一个感到困惑的人。顺便说一句,我没有投反对票。

标签: c++ function virtual abstract


【解决方案1】:

删除createImage 定义周围的#if 0 和#endif。

它们的存在移除了定义,因此Factory 不会覆盖那个纯虚函数,因此仍然是抽象的。

【讨论】:

  • 他们还需要使其成为成员函数。
  • @CaptainObvlious:已经是这样了(尽管缩进具有误导性,而且大量的垂直空白使其更难看到)。
  • 我故意做了这些改变。根据我的问题,如果函数没有在那里定义,那么我应该得到错误,比如必须覆盖对函数或函数的未定义引用。为什么编译器会闪烁错误,例如:无法为工厂分配抽象类型的对象。即使 Factory 不是抽象类型。
  • 它是抽象的,因为正如我所说,您还没有覆盖所有纯虚函数。如果你声明了覆盖但没有定义它,你会得到一个“未定义的引用”。你根本没有声明,所以类仍然是抽象的。
  • 感谢迈克的更新。这是否意味着如果不覆盖派生类中的纯虚函数,那么派生类就会变得抽象?我相信现在很清楚,因此可以从这篇文章中删除反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多