Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Class Extension

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?

like image 886
paul simmons Avatar asked Oct 25 '09 17:10

paul simmons


Video Answer


2 Answers

In C++ you can use free functions, but sometimes extension methods work better when you nest many functions together. Take a look at this C# code:

var r = numbers.Where(x => x > 2).Select(x => x * x);

If we to write this in C++ using free function it would look like this:

auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; });

Not only is this difficult to read, but it is difficult to write. The common way to solve this is to create what is called a pipable function. These functions are created by overloading the | pipe operator(which is just really the or operator). So the code above could be written like this:

auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; });

Which is much easier to read and write. Many libraries use pipable function for ranges, but it could be expanded to other classes as well. Boost uses it in their range library, pstade oven uses it, and also this C++ linq library uses it as well.

If you would like to write your own pipable function, boost explain how to do that here. Other libraries, however, provide function adaptors to make it easier. Pstade egg has a pipable adaptor, and linq provides the range_extension adaptor to create a pipable function for ranges as least.

Using linq, you first just create your function as a function object like this:

struct contains_t
{
    template<class Range, class T>
    bool operator()(Range && r, T && x) const
    { return (r | linq::find(x)) != boost::end(r); };
};

Then you initialize the function using static initialization like this:

range_extension<contains_t> contains = {};

Then you can use your pipable function like this:

if (numbers | contains(5)) printf("We have a 5");
like image 73
Paul Fultz II Avatar answered Oct 25 '22 19:10

Paul Fultz II


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 non-member functions that operate on instances of the class
like image 30
Kristopher Johnson Avatar answered Oct 25 '22 20:10

Kristopher Johnson