views:

245

answers:

7

Hi

Is there a way to add new methods to a class, without modifying original class definition (i.e. compiled .lib containing class and corresponding .h file) like C#'s class extension methods?

+9  A: 

No. C++ has no such capability.

As mentioned in other answers, the common workarounds are:

  • Define a derived class, perhaps with a factory to hide the actual implementation class
  • Define a decorator class
  • Define functions that operate on instances of the class
Kristopher Johnson
+9  A: 

No, you can't do this in C++.

If you want to achieve something like this you have 2 options,

  • You could inherit from the class (if this is an option, it might not be legal as the class may not have been written to allow inheritance)
  • You can write your own wrapper class that has the same interface + your new methods and delegate to the one you want to extend.

I prefer the delegation approach.

Glen
+1 for "favour composition over inheritance"
Rob
Good reply - but I'm not sure that someone asking questions like these knows what to implement when he hears terms like "inherit" or "delegate".
mh
@mh, probably not. but now they know the correct terms to put into a SO or google search
Glen
A: 

Sorry, no. Once your code is in obj, you can not change it. If this can be done in VC partial classes would be supported already. There is one exception though, operator methods can be extended using global functions, pretty like how cout<< is implemented in STL.

Sheng Jiang 蒋晟
+4  A: 

C# class extension methods are mostly syntactic sugar. You get the same functionality with free functions (i.e., functions with a reference or constant reference to your class as their first parameter). Since this works well for the STL, why not for your class?

Pontus Gagge
A: 

Sure you can:


template <typename Ext>
class Class: public Ext { /* ... */ };

That doesn't mean it's the best approach though.

Nikolai N Fetissov
+1  A: 

Generally not. However, if the library does not create instances of the class that require your extension and you are able to modify all places in the app that create an instance of the class and require your extensions, there is a way you can go:

  • Create a factory function that is called at all places that require an instance of the class and returns a pointer to the instance (google for Design Patterns Factory, ...).
  • Create a derived class with the extensions you want.
  • Make the factory function return your derived class instead of the original class.

Example:


    class derivedClass: public originalClass { /* ... */};

    originalClass* createOriginalClassInstance()
    {
         return new derivedClass();
    }
  • Whenever you need to access the extensions, you need to cast the original cast to the derived class, of course.

This is roughly how to implement the "inherit" method suggested by Glen. Glen's "wrapper class with same interface" method is also very nice from a theoretical point of view, but has slightly different properties that makes it less probable to work in your case.

mh
+1  A: 

There is one way in which it can be done. And that's by relaxing your requirements a bit. In C++, people often say that the interface of a class consists not just of its member functions, but of all functions that work on the class.

That is, non-member functions which can be given the class as a parameter should be considered part of its interface.

For example, std::find() or std::sort() are part of the interface of std::vector, even though they aren't members of the class.

And if you accept this definition, then you can always extend a class simply by adding nonmember functions.

jalf