Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Composition - must I wrap all those functions?

I've got a C++ class that describes an object's orientation in 3D space - location, rotation, scale, etc. I have other classes that necessarily need information like that (or a subset of it) - models, terrains, cameras, etc. Now I could make those subclasses of my orientation class, but the Googles have told me to prefer composition over inheritance. This philosophically makes sense - a model is not an orientation, it has one (and yes I know the is-a has-a thing is just a heuristic). Yet it seems needlessly, almost comically inelegant to rewrite the same wrapper methods for all those would-be subclasses just go get at that functionality. Things like model.getOrientation().set_x(1) seem silly as well.

I can see why this wouldn't be "too bad" for small objects, but for this example (and others like it), what's the point of composition if you have to go through hoops anyway to pretend that you're using inheritance? Should I even use it now? I'm almost certain I'm thinking about this improperly.

like image 356
GraphicsMuncher Avatar asked Jun 07 '13 19:06

GraphicsMuncher


3 Answers

There's a cheap way to avoid most of the wrapping boilerplate.

class model : private orientation {
  public:
    using orientation::set_x;
    ... etc ...
};

Private inheritance in C++ doesn't (necessarily) mean "is a". It's more-or-less invisible to outsiders, and is sometimes described as meaning "is implemented in terms of a". That is, you get a limited form of composition that helpfully gives you the ability to expose part or all of the interface of the composed object.

like image 54
Steve Jessop Avatar answered Nov 05 '22 11:11

Steve Jessop


It may seem silly but your model.getOrientation().set_x(1) is probably the way to go.

If you get tired of typing the getOrientation() part, you could try something like this:

Orientation & orient = model.getOrientation();
orient.set_x(1);
orient.set_y(1);
if( orient.check_something() ) {
  //whatever
}
//etc.
like image 45
zindorsky Avatar answered Nov 05 '22 12:11

zindorsky


Write a class for things that have an orientation. Let models, terrains, cameras etc. inherit from that class. If you want to do any wrapping, you need to do it in one class only. Using getters is done so that you can change the way the the orientation is stored in the object.

like image 3
Oswald Avatar answered Nov 05 '22 11:11

Oswald