конструкторы, вызывающие подкласс

0

У меня есть (частично реализованная) иерархия классов, где

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.

Я не могу заставить его работать, и люди предупреждают о разрезании, виртуальных конструкторах и т.д. Но разве такой странный способ настроить его?

Теги:
superclass
subclass
object-slicing

3 ответа

1
Лучший ответ

Наследование должно использоваться для отношений. Таким образом, image<T> представляет собой data<T>, но не наоборот. Нет смысла вызывать метод, специфичный для image<T> для объекта data<T>, который в конце концов может не быть image<T>. Тот факт, что вы хотите это сделать, показывает, что ваш дизайн кода ошибочен. Переосмыслите свой код.

  • 0
    Дело принято. Я хотел закодировать его так, чтобы, например, я мог загрузить image<int> im1("lena.jpg"); и image<int> im2("lena.png"); (с другим конструктором для изображений PNG), а затем используйте их как объекты одного и того же класса. Таким образом, изображение в формате JPEG - это изображение, а изображение в формате PNG - это изображение, но я хочу использовать только тот факт, что они оба являются изображениями после их загрузки. В этом случае лучше кодировать разные параметры ввода-вывода как методы, а не разные классы, включая специфичные для типа файла части, такие как заголовки и т. Д. - именно поэтому я думал, что для разных классов будет лучше.
  • 0
    Я точно знаю, откуда вы пришли. Но лучше подумать об этом для себя!
1

Чтобы реализовать это, вам нужны данные, чтобы быть владельцем реализации, а не базовым классом:

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

Теперь в конструкторе вы можете создать правильный тип реализации и так далее.

  • 0
    Спасибо за это. Тот факт, что для этого требуется другой класс, уже показывает, что это не очень хорошая идея ...
0

Я бы сказал, что это плохой дизайн. Вам не нужно работать с общими классами data чтобы угадать, работаете ли вы с изображениями, если вы точно знаете, что делаете. Используйте класс image или jpgimage где он вам нужен, и сделайте все остальное работать с общим классом data.

  • 0
    Я сделал код более лаконичным, потому что в идеале я хочу что-то, что работает с различными формами числовых данных, может быть изображениями, поверхностями, сигналами и т. Д. Я думаю, что класс image и jpgimage должны быть только методами данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню