Наследование или агрегация - что лучше?
Пишу программу, позволяющую открывать, редактировать и сохранять изображения, пока только в формате 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) Насколько вообще правильно использовать здесь наследование, может стоит использовать агрегацию или что-то ещё?
Заранее спасибо!