【问题标题】:C++ abstract class cannot be instantiatedC++抽象类不能被实例化
【发布时间】:2020-04-29 10:44:12
【问题描述】:

我有这个抽象类

class ImageIO {
protected:
    ImageIO() {}
public:
    virtual bool load(const std::string & filename, const std::string & format) = 0;
    virtual bool save(const std::string & filename, const std::string & format) = 0;
}

以及实现

class Image : public Array2D<Color>, public ImageIO {

private:
    static int case_insensitive(string s) {
        transform(s.begin(), s.end(), s.begin(), tolower);

        if (s.compare("ppm") == 0) {
            return 1;
        }
        return 0;
    }

public:
    bool load(const std::string& filename, const std::string& format) {
        if (case_insensitive(format)) {
            float* data = ReadPPM(filename.c_str(), (int*)width, (int*)height);

            for (int i = 0, j = 0; i < width * height; i++, j += 3) {
                buffer[i] = Color(data[j], data[j + 1], data[j + 2]);
            }

            delete[] data;
            return true;
        }

        return false;
    }

    bool save(const std::string& filename, const std::string& format) {
        if (case_insensitive(format)) {

            float* data = new float[width * height * 3];
            for (int i = 0, j = 0; i < width * height; i++, j += 3) {
                data[j] = buffer[i].x;
                data[j + 1] = buffer[i].y;
                data[j + 2] = buffer[i].z;
            }

            bool write_check = WritePPM(data, width, height, filename.c_str());
            delete[] data;
            return write_check;
        }

        return false;
    }
};

如果我尝试这个,我会不断收到抽象类无法实例化的错误

Image test = Image();

在我的主要。 我也试过在头文件中声明 t=这两种方法

class Image : public Array2D<Color>, public ImageIO {

private:
    static int case_insensitive(std::string);
public:
    bool ImageIO::load(const std::string& filename, const std::string& format);
    bool ImageIO::save(const std::string& filename, const std::string& format);
};

然后我得到未解决的外部符号错误。我实现这两个函数的方式或声明类的方式有问题吗?

编辑:如果我在头文件中声明这两个方法,那么错误是:

error LNK2019: unresolved external symbol "public: virtual bool __thiscall image::Image::[image::ImageIO]::load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?load@?QImageIO@image@@Image@2@UAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z) referenced in function _main
error LNK2019: unresolved external symbol "public: virtual bool __thiscall image::Image::[image::ImageIO]::save(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?save@?QImageIO@image@@Image@2@UAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z) referenced in function _main

如果我不这样做,错误是

error C2259: 'image::Image': cannot instantiate abstract class

我还添加了覆盖,没有任何变化。

【问题讨论】:

  • 没有minimal reproducible example 很难查明问题。
  • 您的代码包含许多错误,导致无法编译。例如,在您的 ImageIO 类声明和“虚拟布尔加载”函数声明的右大括号处,分号丢失。还值得一提的是,即使基类函数是纯虚函数以提高可读性,您也可能应该使用 override 关键字。
  • 在派生类中声明重写方法后使用override 说明符。它将确保您实际上覆盖了它们。
  • 你是如何编译这个的,项目目录结构是什么? ImageImageIO 在哪个文件中声明和定义?
  • 我同意覆盖说明符:它节省了大量时间。由于您使用的是多重继承,您确定 Array2D 中没有抽象的东西,并且这个类也不会提供一些加载和保存吗?

标签: c++ visual-studio c++11 visual-c++ abstract-class


【解决方案1】:

要专门回答有关未解析外部符号的问题,您不需要保存/加载函数上的 ImageIO 父说明符。您声明Image 本身具有这些功能,这些功能会覆盖父级上的抽象功能。然后,您需要在 cpp 文件中实现它们时指定 Image

图像.hpp

class Image : public Array2D<Color>, public ImageIO {

private:
    static int case_insensitive(std::string);
public:
    bool load(const std::string& filename, const std::string& format) override;
    bool save(const std::string& filename, const std::string& format) override;
};

图像.cpp

bool Image::load(const std::string& filename, const std::string& format) {
    if (case_insensitive(format)) {

        //etc.
    }

    return false;
}

bool Image::save(const std::string& filename, const std::string& format) {
    if (case_insensitive(format)) {

       //etc.
    }

    return false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 2019-10-27
    • 2013-08-23
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多