Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending an existing class like a namespace (C++)?

I'm writing in second-person just because its easy, for you.

You are working with a game engine and really wish a particular engine class had a new method that does 'bla'. But you'd rather not spread your 'game' code into the 'engine' code.

So you could derive a new class from it with your one new method and put that code in your 'game' source directory, but maybe there's another option?

So this is probably completely illegal in the C++ language, but you thought at first, "perhaps I can add a new method to an existing class via my own header that includes the 'parent' header and some special syntax. This is possible when working with a namespace, for example..."

Assuming you can't declare methods of a class across multiple headers (and you are pretty darn sure you can't), what are the other options that support a clean divide between 'middleware/engine/library' and 'application', you wonder?

like image 753
James Avatar asked Oct 23 '08 03:10

James


4 Answers

My only question to you is, "does your added functionality need to be a member function, or can it be a free function?" If what you want to do can be solved using the class's existing interface, then the only difference is the syntax, and you should use a free function (if you think that's "ugly", then... suck it up and move on, C++ wasn't designed for monkeypatching).

If you're trying to get at the internal guts of the class, it may be a sign that the original class is lacking in flexibility (it doesn't expose enough information for you to do what you want from the public interface). If that's the case, maybe the original class can be "completed", and you're back to putting a free function on top of it.

If absolutely none of that will work, and you just must have a member function (e.g. original class provided protected members you want to get at, and you don't have the freedom to modify the original interface)... only then resort to inheritance and member-function implementation.

For an in-depth discussion (and deconstruction of std::string'), check out this Guru of the Week "Monolith" class article.

like image 175
Tom Barta Avatar answered Oct 05 '22 20:10

Tom Barta


Sounds like a 'acts upon' relationship, which would not fit in an inheritance (use sparingly!).

One option would be a composition utility class that acts upon a certain instance of the 'Engine' by being instantiated with a pointer to it.

like image 27
Redbeard Avatar answered Oct 05 '22 19:10

Redbeard


  • Inheritance (as you pointed out), or
  • Use a function instead of a method, or
  • Alter the engine code itself, but isolate and manage the changes using a patch-manager like quilt or Mercurial/MQ

I don't see what's wrong with inheritance in this context though.

like image 33
Menkboy Avatar answered Oct 05 '22 19:10

Menkboy


If the new method will be implemented using the existing public interface, then arguably it's more object oriented for it to be a separate function rather than a method. At least, Scott Meyers argues that it is.

Why? Because it gives better encapsulation. IIRC the argument goes that the class interface should define things that the object does. Helper-style functions are things that can be done with/to the object, not things that the object must do itself. So they don't belong in the class. If they are in the class, they can unnecessarily access private members and hence widen the hiding of that member and hence the number of lines of code that need to be touched if the private member changes in any way.

Of course if you want to access protected members then you must inherit. If your desired method requires per-instance state, but not access to protected members, then you can either inherit or composite according to taste - the former is usually more concise, but has certain disadvantages if the relationship isn't really "is a".

like image 20
Steve Jessop Avatar answered Oct 05 '22 19:10

Steve Jessop