I'm currently learning C++ and for this I'm writing a simple image-converter.
I would like to have a base image class that contains different memorylayouts of the image, say DXTn or BMP.
How do I properly design my class that can contain these different datatypes?
Is there a better way of storing the memory in a (smart)pointer?
class Image
{
public:
void loadDXT() { }
void loadBMP() { }
private:
char* data1;
std::unique_ptr< char* > data2;
}
Or would it be better to derive a more specific classfrom a simple baseclass:
class baseImage
{
public:
enum imgType { BMP , DXT };
void load() = 0;
}
class BMPImage : public baseImage
{
//bmp specific stuff here
}
This isn't only specific to this imageclass, I'm in general curious how do I design classes that contain different data member.
Thank you.
I agree with jwg a virtual abstract interface would make your life easier.
For example:
class BaseImage//base class
{
public:
virtual void DoThingsRelatedToAllImages_1()=0;
virtual void DoThingsRelatedToAllImages_2()=0;
//...and so on and whatever else
private:
int DataUsedForAllImageTypes;
};
//this is our child class
class Bmp: public BaseImage
{
private:
int DataUsedOnlyForBmpTypeImages;
};
void Bmp::DoThingsRelatedToAllImages_1()
{
//Do Whatever this function should do for a bitmap
}
void Bmp::DoThingsRelatedToAllImages_2()
{
//Do Whatever this function should do for a bitmap
}
Just keep in mind than an abstract class cannot be instantiated because it has no implementation. If you go with a virtual class not an abstract class you in theory could have typeless image classes to work with if you needed it. all you would need to do is provide a basic implementation to your virtual class.
For example:
class BaseImage//base class
{
public:
virtual void DoThingsRelatedToAllImages_1();
virtual void DoThingsRelatedToAllImages_2();
//...and so on and whatever else
private:
int DataUsedForAllImageTypes;
};
void BaseImage::DoThingsRelatedToAllImages_1()
{
//Do Whatever this function should do for a base image
}
void BaseImage::DoThingsRelatedToAllImages_2()
{
//Do Whatever this function should do for a base image
}
//this is our child class
class Bmp: public BaseImage
{
private:
int DataUsedOnlyForBmpTypeImages;
};
void Bmp::DoThingsRelatedToAllImages_1()
{
//Do Whatever this function should do for a bitmap
}
void Bmp::DoThingsRelatedToAllImages_2()
{
//Do Whatever this function should do for a bitmap
}
Hopefully this was a helpful example.
I would also say that Template classes could be very useful but I will leave you to figure that out as I do not really want to go into that right now.
Good luck, Let me know if i can clarify anything i said.
I would say that the second method is definitely what you need. You are basically specifying an interface - what you would use an abstract class for in C++. The base class should contain all the functions that you think every image should be able to provide - probably as pure virtual functions since there is no 'general image' which implements these the same way for any image. (You might have things like common metadata which have the same structure for every image type, and these could be dealt with by methods in the base class.)
Then each class will implement the virtual functions based on its own private data stored in the way that makes sense for that type of image. If some image types share some, but not all operations, you could have several layers of inheritance, eg RasterImage inherits from Image and BMPImage and PNGImage inherit from RasterImage.
There are libraries around that do a lot of this stuff to permit rendering of graphs, vector objects, etc. into multiple formats. You probably don't want to use a big outside library since you are doing this to teach yourself, but you might like to look at how one is structured to get some ideas. (Note that some graphics libraries will justifiably have a much more complex and flexible structure then you probably want to imitate. If there are so many layers of abstraction and inheritance that you can't keep track of them, it might not be the best source to learn by example from.)
Related
In below code I have abstract class TestAlgModule which I will be exposing to library users and there are several functionalities they can use such as VOLUME, MIXER and so on. However, suppose users need a new function which is added only in MixerManager then I need to add that in TestAlgModule abstract class and now suddenly all the derived class needs to add that without any benefit.
How do I avoid this?
#include <iostream>
using namespace std;
enum {VOLUME, MIXER, UNKNONWN};
class TestAlgModule {
public:
virtual void open(int type) = 0;
virtual void close(int type) = 0;
};
class volumeManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
};
class mixerManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
void differentFunction() {};
};
/* users calls this to get algModule and then call functions to get the job done */
TestAlgModule *getTestAlgModule(int type) {
switch(type) {
case VOLUME:
return new volumeManager();
case MIXER:
return new mixerManager();
default:
break;
}
return nullptr;
}
int main() {
TestAlgModule * test = getTestAlgModule(MIXER);
test->open();
//test->differentFunction(); this can't be called as it is not part of abstract class and users are exposed only abstract class
return 0;
}
If something is not clear please let me know and I will do my best to answer it. I am looking for a better way to do this i.e. change in VolumeManager should be independent of MixerManager.
If you want to use an abstract factory, like you did in above code, then you need to return a pointer to the base class. That is correct. And then you need to invoke all functions through the base pointer.
By the way, please do not use raw pointers. Please use std::unique pointers instead.
There are 2 possible solutions.
Add the interface functions as a none pure, but still virtual function to your base class, with a default behaviour.
virtual void differentFunction() {}
Because of the other pure functions, the base class is still abstract. This may lead to a fat interface. But in many cases it is an acceptable solution.
The second possibility is to downcast the base class pointer to your needed pointer, using dynamic_cast and checking the return value of the dynamic cast.
if(mixerManager* mm = dynamic_cast<mixerManager*>(test)) {
mm->differentFunction();
}
All this depends of course on the overall design and what you want to achieve. But the above 2 are the standard patterns.
There are also other design patterns that may fit your needs, like builder or prototype. Please check.
I have a class hierarchy that I designed for a project of mine, but I am not sure how to go about implement part of it.
Here is the class hierarchy:
class Shape { };
class Colored { // Only pure virtual functions
};
class Square : public Shape { };
class Circle : public Shape { };
class ColoredSquare : public Square, public Colored { };
class ColoredCircle : public Circle, public Colored { };
In part of my project, I have a std::vector of different type shapes. In order to run an algorithm though, I need to put them in a std::vector of colored objects (all of which are derived types of different concrete shapes, so I need a method to cast a Square into a ColoredSquare and a Circle into a ColoredCircle at runtime.
The tricky thing is that the 'shape' classes are in a different library than the 'colored' classes.
What is the best method to acomplish this? I have thought about doing a dynamic_cast check, but if there is a better way, I would rather go with that.
Edit 1:
Here's a bit better of an Example:
class Traceable {
public:
// All virtual functions
virtual bool intersect(const Ray& r) = 0;
// ...
};
class TraceableSphere : public Sphere, public Traceable {
};
class IO {
public:
// Reads shapes from a file, constructs new concrete shapes, and returns them to
// whatever class needs them.
std::vector<Shape*> shape_reader(std::string file_name);
};
class RayTracer {
public:
void init(const std::vector<Shape*>& shapes);
void run();
private:
std::vector<Traceable*> traceable_shapes;
};
void RayTracer::init(const std::vector<Shape*>& shapes) {
// ??? traceable_shapes <- shapes
}
void RayTracer::run() {
// Do algorithm
}
You could use the decorator pattern:
class ColorDecorator public Colored
{
ColorDecorator(Shape* shape): m_shape(shape) {}
... //forward/implement whatever you want
};
If you want to store a Square in a Colored vector, wrap it in such a decorator.
Whether this makes sense is questionable though, it depends on your design and the alternatives. Just in case, also check out the visitor pattern (aka double dispatch) which you could use to just visit a subset of objects in a container or treat them differently depending on their type.
Looks like you are going to design the class library in a "is-a" style, welcome to the Inheritance-Hell.
Can you elaborate a bit about your "algorithm" ?
Typically it is bad design if you need to "type-test" on objects, since that is what you want to avoid with polymorphism. So the object should provide the proper implementation the algorithm uses (design-pattern: "strategy"), advanced concepts utilize "policy-based class design".
With careful design, you can avoid casting. In particular, care for SRP. Implement methods carefully so that they use a single Interface to achieve a single goal/fulfill a single responsibility. You have not posted anything about the algorithms or how the objects will be used. Below is a hypothetical sample design:
class A {
public:
void doSomeThing();
};
class B{
public:
void doSomeOtherThing();
};
class C:public A,public B{};
void f1( A* a){
//some operation
a->doSomeThing();
//more operation
}
void f2(B* b){
//some operation
b->doSomeOtherThing();
//more operation
}
int main(int argc, char* argv[])
{
C c;
f1(&c);
f2(&c);
return 0;
}
Note using the object c in different context. The idea is to use only the interface of C that is relevant for a specific purpose. This example can have classes instead of the functions f or f2. For example, you have some Algorithms classes that do some operation using the objects in the inheritance hierarchy, you should create the classes such that they perform a single responsibility, which most of the time requires a single interface to use, and then you can create/pass objects as instance of that interface only.
Object-oriented programming only makes sense if all implementations of an interface implement the same operations in a different way. Object-orientation is all about operations. You have not shown us any operations, so we cannot tell you if object-orientation even makes sense for your problem at all. You do not have to use object-oriented programming if it doesn't make sense, especially in C++, which offers a few other ways to manage code.
As for dynamic_cast -- in well-designed object-oriented code, it should be rare. If you really need to know the concrete type in some situation (and there are such situations in real-life software engineering, especially when you maintain legacy code), then it's the best tool for the job, and much cleaner than trying to reimplement the wheel by putting something like virtual Concrete* ToConcrete() in the base class.
I think the simplest & cleanest solution for you would be something like the following similar to what Chris suggests at the end.
class Shape {
virtual Colored *getColored() {
return NULL;
}
};
class Colored { // Only pure virtual functions
};
class Square : public Shape { };
class Circle : public Shape { };
class ColoredSquare : public Square, public Colored {
virtual Colored *getColored() {
return this;
}
};
class ColoredCircle : public Circle, public Colored {
virtual Colored *getColored() {
return this;
}
};
I do not completely understand this statement though
" The tricky thing is that the 'shape' classes are in a different library than the 'colored' classes."
How does this not allow you to do what's being suggested here (but still allow you to create a class ColoredSquare) ?
It seems to be the prevailing opinion that using protected data members is a bad idea. I'm wondering what a good alternative would be in a specific case.
Take the following class called CModule, which represents a audio module (Amiga-style tracker music). Many different module formats exist but the only difference between them is in file format (Loading) and audio effects handling. CModule holds all the common functionality, the derived classes implement loading and effects for each specific format.
class CModule
{
public:
CModule(string Filename); //Song file name to load.
//Common methods...
void Play();
void Stop(); //Etc...
protected:
//Derived class should implement these with format specific code.
//Base class code calls these when needed.
virtual void Load()=0;
virtual void Effects()=0;
//Song information/data.
vector<CInstrument> Instruments;
vector<CPattern> Patterns;
//And much, MUCH more...
};
Almost all the data members are protected since the derived class's Load() function needs to fill them all. This is considered bad since it can break encapsulation if someone derives a class from the derived class. What would be the proper way to solve this problem? I've already found that using getters/setters is considered bad too.
Many thanks to anyone taking the time to read this :)
There's nothing wrong with using protected data members if using private won't work for your solution, using public data members however is almost never a good idea (however it can be sometimes too).
I would probably make your vectors private in this case but simply create getter and setter methods. Something along the lines of:
class CModule
{
public:
CModule(string Filename); //Song file name to load.
//Common methods...
void Play();
void Stop(); //Etc...
protected:
//Derived class should implement these with format specific code.
//Base class code calls these when needed.
virtual void Load()=0;
virtual void Effects()=0;
void AddInstrument(CInstrument instrument)
{
Instruments.push_back(instrument);
}
Instrument GetInstrument(int index)
{
return Instruments[index];
}
int InstrumentCount()
{
return Instruments.size();
}
private:
//Song information/data.
vector<CInstrument> Instruments;
vector<CPattern> Patterns;
//And much, MUCH more...
};
This is a start just for instruments, you'll also have to take a similar approach with patterns. Alternatively you could also just pass back the vector but this is a little more encapsulated.
Also note that I am doing this off the top of my head and haven't tested it against typos of whatever but hopefully it conveys the idea.
Suppose I have following inheritance tree:
SDLBullet inherits from Bullet inherits from Entity
EnemyBullet inherits form Bullet inherits from Entity
Now I need a new class, SDLEnemyBullet, which needs the draw as implemented in SDLBullet, and the collision as implemented in EnemyBullet. How would I do this? Is this to be solved using multiple inheritance? If not, feel free to edit my question and title. If so, how would I implement such thing?
Some code examples below:
class Entity {
bool collision(Entity) = 0;
void draw() = 0;
}
class Bullet : Entity {
bool collision(Entity) {/*some implementation*/};
void draw() {/*draw me*/};
}
class SDLBullet : Bullet {
void draw() {/*draw me using SDL*/};
}
class EnemyBullet : Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
}
class SDLEnemyBullet : ????? {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
Any help is much appreciated!
(BTW: This is a school project, and an inheritance tree like this was suggested to us. No one is stopping us from doing it different and better. Thats why I asked the question.)
The textbook solution involves multiple and virtual inheritance.
class SDLBullet : public virtual Bullet {
void draw() {/*draw me using SDL*/};
};
class EnemyBullet : public virtual Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
};
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
// just one Bullet subobject here
};
Normally, collision stuff is done using multiple dispatch, or in C++, who hasn't this feature, using the visitor pattern.
BUT
why don't you have a hierarchy like this instead ?
class Entity;
class Bullet : public Entity
{
public:
virtual draw();
}
class FriendlyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
class EnnemyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
This would work too, and wouldn't require multidispatch or multiple inheritance
You need to specify a comma separated list of the super classes:
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
It looks like you're making a game (engine). To avoid the need for complex inheritance structures like this favor composition over inheritance for entities i.e. Have an entity object that contains separate 'component' objects for rendering etc. That way you can mix and match the components however you like without having an explosion of classes with all the different combinations of super classes.
Here's a good article on the subject: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
Prefer composition over inheritance
You don't need inheritance to combine stuff that's not related like that. Make up basic objects (entities?) for game logic, physics, sound, input, graphics (which may use inheritance) and combine those a GameObject which just has an array of said objects.
Some nifty cross-linking is useful since they will all share a Frame or Transform, but that can be done during creation by iterating over all other objects and using dynamic_cast... (it's useful if you do not need to depend on initialization order).
But there's really no need to build this with inheritance. It doesn't fit your usecase properly. (Although virtual inheritance is useful, it's not a good thing to use inheritance to force different things to become the same, i.e. making everything be a something, instead of being made up of different parts (render, damage, sound, etc...).
Read this and this for more info, or just click the title to google for it. :)
I have the following existing classes:
class Gaussian {
public:
virtual Vector get_mean() = 0;
virtual Matrix get_covariance() = 0;
virtual double calculate_likelihood(Vector &data) = 0;
};
class Diagonal_Gaussian : public Gaussian {
public:
virtual Vector get_mean();
virtual Matrix get_covariance();
virtual double calculate_likelihood(Vector &data);
private:
Vector m_mean;
Vector m_covariance;
};
class FullCov_Gaussian : public Gaussian {
public:
virtual Vector get_mean();
virtual Matrix get_covariance();
virtual double calculate_likelihood(Vector &data);
private:
Vector m_mean;
Matrix m_covariance;
};
As you see, the class Gaussian acts as an interface but doesn't have any implementation. This is all working fine.
Now I want to make an class "AdaptedGaussian" where the data vector provided to the calculated_likelihood will be changed before the likelihood is calculated.
Some requirements:
The AdaptedGaussian must be a child-class of Gaussian
AdaptedGaussian must be able to "wrap" or "be an instance of" every possible Gaussian class
AdaptedGaussian must be constructed from an already existing Gaussian Object
The idea I have now is:
class Adapted_Gaussian : public Gaussian {
private:
Gaussian* m_g;
public:
virtual Vector get_mean() { return m_g->get_mean(); }
virtual Matrix get_covariance() { return m_g->get_covariance(); }
virtual double calculate_likelihood(Vector &data)
{
//do something with data
return g->calculate_likelihood(Vector &data);
}
}
There are maybe some disadvantages:
For every method (and there are more than showed here) a dummy method must be written in the new class
If Gaussian is ever extended, and this class would be forgotten, nasty bugs can appear.
Am I doing this in the right way? Or are there better methods to implement this?
Is there maybe a good way to standard delegate every non-implemented method to the same named method of m_g?
Looks good, I think this is a pretty classic implementation of the Adapter pattern. Just don't forget to declare a virtual destructor for your Gaussian class. As for the disadvantages.
The way Java class library deal with the dummy method problem is to create a dummy class that provides empty implementation for every single method. All classes that do not want to implement every single method can just inherit from this dummy class and selectively override methods that interests them.
If you extend your Gaussian class with few more methods, as long as you declare them as pure virtual method you will get a compiler error in your child class file anyway.
As you point out writing a lot of basic pass-through functions is tedious and adds an implied maintenance overhead. Also, having a pointer member implies extra (albeit simple) lifetime management issues of the owned pointer. Probably the simplest way to address these issues is to make AdaptedGaussian a template, templated on the specific instance of Gaussian to be adapted.
template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
virtual double calculate_likelihood(Vector &data)
{
// do something with data
return BaseGaussian::calculate_likelihood(Vector &data);
}
};
This does rely on all adapted instances of Gaussian being default constructible, or at least conforming to a common constructor signature.
If you want to construct an AdaptedGaussian from an existing XXXGaussian, then so long as the XXXGaussian is itself copyable you can add a suitable constructor:
template<class BaseGaussian> class AdaptedGaussian : public BaseGaussian
{
public:
AdaptedGaussian(const BaseGaussian& other) : BaseGaussian(other)
{
}
// ...
};
This could maybe also be solved by a Strategy Pattern.
It seams to me, that duffymo also was thinking in this direction with "composition". Change the design in that way, that the base class calls some method of an other object it contains. This object contains the coding for calculate_likelihood. Either the whole method can be deferred or only the modifications (in the second case, the default would be to just do nothing).
E.g.: (corrected version)
class Gaussian {
private:
Cl_Strategy* m_cl_strategy;
public:
Gaussian(Cl_Strategy* cl_strategy) {
m_cl_strategy = cl_strategy;
};
virtual Vector get_mean() = 0;
virtual Matrix get_covariance() = 0;
virtual double _calc_likelihood(Vector &data) = 0;
virtual double calculate_likelihood(Vector &data) {
m_cl_strategy->do_your_worst(this, data);
return _calc_likelihood(data);
};
};
I hope, I got that one right, my C++ is a little bit dusted ...
_calc_likelihood must be implemented by subclasses and calculate_likelihood binds all together.
Of course, this solution adds a little overhead, but in some situations, the overhead might be OK.
In Java, it's common to have both an interface and an abstract class that implements it to provide default behavior for all methods. (See Joshua Bloch's design of the Collections API in java.util package.) Perhaps that can help you here as well. You'll give clients a choice of using either the interface or the abstract class.
You can also try composition. Pass an instance of an adapted Gaussian to subclasses and defer behavior to it.