У меня есть (частично реализованная) иерархия классов, где
template<typename T> {
class data {
data ( string s ) {}; // loads from file
...
}
class image: public data <T> {
image ( string s ) {}; // loads from file
...
}
class jpgimage : public image<T> {
jpgimage ( string s ) {}; // loads from file
...
}
// other image types
}
Теперь в остальной части моего кода я хотел бы иметь возможность абстрагироваться от того, является ли что-то изображением в формате JPEG или даже изображением, поэтому я хотел бы работать с data
, Но в то же время я хотел бы передать в эти функции команды, специфичные для изображений JPEG.
Так что если я позвоню data<int> img("lena.jpg");
который оказывается изображением, даже изображением в формате JPEG, я хотел бы, чтобы конструктор данных вызывал конструктор изображений, который, в свою очередь, вызывает конструктор jpgimage.
Я не могу заставить его работать, и люди предупреждают о нарезке, виртуальных конструкторах и т. Д. Но так ли это странный способ настроить это?
Наследование должно быть использовано для это отношения. Итак, image<T>
это data<T>
, но не наоборот! Нет смысла вызывать метод, специфичный для image<T>
для data<T>
объект, который в конце концов не может быть image<T>
, Тот факт, что вы хотите сделать это, показывает, что ваш дизайн кода имеет недостатки. Переосмыслите свой дизайн кода.
Для реализации этого вам понадобятся данные, чтобы быть владельцем реализации, а не базовый класс:
template<typename T>
class base_data {
base_data ( string s ) {} // loads from file
// ...
};
template<typename T>
class image: public base_data <T> {
image ( string s ) {} // loads from file
...
};
template<typename T>
class jpgimage : public image<T> {
jpgimage ( string s ) {} // loads from file
// ...
// other image types
};
template<typename T>
class data {
data ( string s ) {
if(is_jpeg( s )) impl = new jpeg_data<T>( s );
// ...
} // loads from file
// ...
private:
base_data<T> *impl;
};
Теперь в конструкторе вы можете создать правильный тип реализации и так далее.
Я бы сказал, что это плохой дизайн. Вам не нужно работать с универсальным data
классы только для Угадай работаете ли вы с изображениями, если точно знаете, что делаете. Использовать image
или же jpgimage
класс, где вам это нужно, и заставить все остальное работать с универсальным data
учебный класс.