Question

I have a (partally implemented) class hierarchy where

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
}

Now in the rest of my code I would like to be able to abstract from whether something is a jpeg image or even an image, so I would like to work with data. But at the same time I would like to pass commands specific to jpeg images to those functions.

So if I call data<int> img("lena.jpg"); which turns out to be an image, even a jpeg image, I would like the data constructor to call the image constructor, which in turn calls the jpgimage constructor.

There is no way I can get it to work, and people warn about slicing, virtual constructors, etc. But is this such a strange way to set it up?

Was it helpful?

Solution

Inheritance is to be used for is a relationships. So, an image<T> is a data<T>, but not the other way around! It makes no sense to call a method specific to image<T> for a data<T> object, which after all may not be an image<T>. The fact that you want to do that shows that your code design is flawed. Rethink your code design.

OTHER TIPS

To implement that you would need data to be owner of implementation, not base class:

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

Now in constructor you can create proper type of implementation and so on.

I'd say it's a bad design. You don't need to work with generic data classes just to guess whether you work with images, if you know for sure that you do. Use the image or jpgimage class where you need it, and make everything else work with a generic data class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top