Абстрактный класс C ++ не может быть создан - PullRequest
3 голосов
/ 12 января 2020

У меня есть этот абстрактный класс

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

Я также добавил переопределение и ничего не изменилось.

1 Ответ

0 голосов
/ 16 января 2020

Чтобы конкретно ответить на вопрос о неразрешенных внешних символах, вам не нужен родительский спецификатор ImageIO в функциях сохранения / загрузки. Вы заявляете, что Image сам имеет те функции, которые переопределяют абстрактные функции родительского элемента. Затем вам нужно будет указать 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;
};

Image. 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;
}
...