-
Inheritance Question
Hey there,
image i have a class called BMPImage. The class looks simplified like this:
Code:
#include "Matrix.h"
class BMPImage
{
public:
BMPImage(const char *filename);
~BMPImage(void);
private:
Matrix<float> *data;
};
data is allocated in the constructor of BMPImage.
The Matrix class looks like this:
Code:
template<typename T>
class Matrix
{
public:
Matrix(const int nRows, const int nCols, const int nChannels);
T get(const int row, const int col);
void set(const int row, const int col, T value);
private:
T *data;
};
data is aswell allocated in the constructor.
BMPImage should have much of the same functionality as a Matrix. This would actually be solved by letting BMPImage inherit from Matrix. This is what i actually want to do.
The problem is, that the two constructors look quite different for Matrix and BMPImage.
What would be an elegant way to implement this?
I think of something like this
Code:
class BMPImage : public Matrix<float>
{
public:
BMPImage(const char *filename)
{
// read the BMP File
// set nRows, nCols of Matrix accordingly to the BMP file
}
};
This would require Matrix to have a default constructor, which would complicate the Matrix class somewhat more than i like to.
Another way would be to implement getters and setters in BMPImage which would simply wrap the getters and setters of the Matrix where the BMP Data is stored.
Any ideas on what solution would be more adequate?
Thanks and best regards, threahdead
-
From a design perspective, inheritence is used to represent "is a" relationships between types. For example, "Dog" is a "Mammal". From what you say, the only reason you want to use inheritance is because of similar interfaces which is necessary but usually considered insufficient from a design perspective. Generally it is considered best if class hierarchies comply with the Liskov Substitution Principle which, roughly speaking, means the derived classes are specialised (rather than extended) versions of the base class. You are breaking that guideline - the fact you have a constructor with different signature (accepting a filename) hints strongly at that.
Generally, you are better off using containment (i.e. BMPImage contains and manages an instance of Matrix<float>). In practice, that means writing forwarding functions, and those forwarding functions are able to perform additional error checking if desired (for example range checking).
That said, the compiler will let you do it either way. However, it is better to stick with accepted design principles, in order to avoid getting into design habits that confuse other programmers.
-
-
Thank you very much for your answers. It helped me alot to see clearly again, how OO code should be designed.
I tend to forget some principles when doing a long coding session. ;)