Наследование или агрегация - что лучше?

Пишу программу, позволяющую открывать, редактировать и сохранять изображения, пока только в формате BMP, но с расчётом на то, что список форматов может увеличиться. Создал класс image, описывающий собственно изображение (длина, ширина, массив со всеми пикселями). Унаследовал от него класс image_bmp, который добавляет специфические для BMP файла члены и функции (заголовки, чтение из файла, запись в файл). После этого понял, что по завершении редактирования мне нужно будет создавать объект класса image_bmp на основе объекта image (то есть объект дочернего класса на основе объекта родительского). В этом месте я уже призадумался, нормально ли это, или более правильно было бы использовать агрегацию и просто хранить в классе image_bmp ссылку на объект класса image, а наследование не использовать. После этого решил сделать поля данных родительского класса image protected, и оказалось, что теперь я не могу конструировать объект дочернего класса, принимая в качестве аргумента объект родительского, так как почему-то не имею из этого конструктора прямого доступа к полям родительского класса (хотя они и protected, а не private).

Код примерно такой:

class image
{
protected:
    uint32_t width;
    uint32_t height;
    std::vector<pixel> pixels;
public:
    image() : width(0), height(0), pixels(0) {};
    image(uint32_t w, uint32_t h) : width(w), height(h), pixels(w* h) {};
};


class image_bmp : public image
{
private:
    BitmapFileHeader bmfh;
    DIBheader bmif;
public:
    // создание объекта на основе файла .bmp
    image_bmp(const std::string& filename);

    image_bmp(const image& IMG) : image(IMG), bmfh{}, bmif{}
    {
        // заполнение заголовков, вот здесь нет доступа к полям protected объекта IMG
        bmif.width = IMG.width;
        ...
    }

    void write_to_file(const std::string& filename);    
};

Собственно, вопросы: 1) Почему нельзя обратиться к protected полям объекта родительского класса, переданного в качестве аргумента конструктора дочернего? 2) Насколько вообще правильно использовать здесь наследование, может стоит использовать агрегацию или что-то ещё?

Заранее спасибо!


Ответы (0 шт):