C++ Class Extension - c++

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?

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

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.

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?

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");

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.

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.

You cannot add methods or data physically to the class file which is in binary form. However, you can add methods and data (functionality and state) to the objects of that class by writing extension classes. This is not straight forward and requires Meta-Object-Protocol and Interface based programming. You need to do a lot to achieve this in C++ since it does not support Reflection out of the box. In such an implementation when you query for the interface implemented by your new extension class via the original class object pointer, the meta object implementation returns that interface pointer via the meta class object for the extension class that it creates at runtime.
This is how many customizable (plugin based) software application frameworks work. However, you must remember that it requires many other MOP mechanisms to be written to instanciate meta objects for all the classes using dictionaries in which the object relations are described and give the correct interface pointers for the original and extended class objects. Dassault Systemes' CATIA V5 is written in such an architecture called CAA V5 where you can extend existing components by writing new extension classes with the desired functionality.

Sure you can:
template <typename Ext>
class Class: public Ext { /* ... */ };
That doesn't mean it's the best approach though.

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.

Related

C/C++: Should serialization methods be class members?

Suppose we have a complex (i.e. non-primitive) class ComplexObject defined below:
class A{...};
class B{...};
class C{...};
class ComplexObject
{
private:
A _fieldA;
B _fieldB;
C _fieldC;
};
I would like to implement a serializer that serializes instances of ComplexObject into binary form. From my experience in C#, I have seen essentially 3 distinct ways to implement a serializer.
Define a serialize(binarystream&) method in ComplexObject's definition and those of the "child" classes, A, B, and C. The serialize method defined in ComplexObject will recursively call those of the child members.
Create a separate class that contains methods to serialize each of ComplexObject, A, B, and C. The method used to serialize ComplexObject will recursively call those of the child members. Of course, getters will have to be defined in the classes to retrieve private fields for the serializer.
Use reflection to generate a template of the object and to write all serializable fields into a table according to the generated template.
Unfortunately I believe reflection will be extremely hard to utilize in C++, so I shall stay away from the third option. I have seen options 1 and 2 both been used very often (in C#).
An advantage that option 1 possess over option 2 is that it allows for classes that derive from ComplexObject, by marking the serilalize(binarystream&) method virtual. However, it would add to the list of member functions of an object and confuse programmers. You don't see a serialize method being defined in std::string, do you?
On the other hand, option 2 takes out and groups all serialization methods together to make things a bit neater. However, I suppose it isn't as easy to accommodate for derived classes of ComplexObject.
Under which circumstances should each of the options (1 and 2) be used?
I choose "both". Serialization has components in the object and (templated) free standing functions.
For example:
class Serialization_Interface
{
public:
virtual void load_from_buffer(uint8_t*& buffer_ptr) = 0;
};
void Load_From_Buffer(unsigned int& number, uint8_t*& buffer_pointer)
{
number = *((unsigned int *) buffer_ptr);
buffer_pointer += sizeof(unsigned int);
}
template <class Object>
void Load_From_Buffer(Object& obj, uint8_t*& buffer_pointer)
{
obj.load_from_buffer(buffer_pointer);
}
Don't limit yourself to two choices. There's always a third alternative. :-)
Also, don't reinvent the wheel, check out Boost::serialization.
C++ doesn't have reflection, but that doesn't mean serialization code needs to be written by hand.
You can use a code generator (for example, protocol buffers) to create the serialization code from a simple description. Of course, that description format doesn't support the rich C++ features for creating your public API, but you can take the data structure type created by the code generator and embed that inside your "real" class, either directly embedded or via pimpl. That way you write all non-serialization behavior in your class, but it doesn't have any data of its own, it relies on the serialization object to store the data.
It's basically like your method #2, but applying inversion of control. The serializer logic doesn't reach into your class to get access to the data, instead it becomes responsible for storing the data where your class also can use it.
I wold not bother with self-made serializer.
(Notice that designing deserialization is harder than serialization...)
I would rather use something line:
https://code.google.com/p/protobuf/
http://android-developers.blogspot.com/2014/06/flatbuffers-memory-efficient.html
or boost (you can also check how they solved similar problem)
http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/index.html
Getting back to your dilemma.
Grouping all serialization code in a single class is a bad idea, because this class would grown with each new serializable object. You could use friend "serializer" class for each "serializable" class,
or use friend method / operator<<.
But there is no perfect solution and it is not easy task. If you can, use lib.

C++ design: subclass, or are there better ways?

I have a Cheese class. In my program, I deal a lot with collection of cheeses, mostly vector<Cheese> objects.
I want to be able to eat() a cheese collection, something like this:
vector<Cheese> cheeses;
//cheeses = ...
cheeses.eat();
How to do this? How do I add a new member function to the vector<Cheese> class? Should I just subclass the vector<Cheese> class, name the subclass CheeseCollection and add the member function there, or are there any better ways?
Coming from Objective-C, I'm used to categories, which allowed me to add functions ("methods") to classes. Is something like that available in C++, or is it considered more natural to subclass like crazy in C++?
In C++ you simply wouldn’t use a member function for this – use a free function:
void eat(std::vector<Cheese> const& cheeses) {
// …
}
This is a close equivalent to those Obj-C categories even though the syntax differs (and you’re not using member access).
The standard library container classes weren’t designed to be subclassable so that approach will fail. What you could do is use composition instead of inheritance – i.e. have a CheeseCollection class which contains a vector of cheeses as a member. This may have some advantages, depending on your overall design. However, in general the above is the most C++ic solution.
Neither -- what you want is an algorithm. Assuming you have an eat that already knows how to eat one Cheese object, applying it to an entire collection would be something like:
std::for_each(cheeses.begin(), cheeses.end(), eat).
Unlike some other languages, C++ does not maintain a slavish adherence to object orientation, even when it makes no real sense.
One thing you can do is define your own class which uses (encapsulates) the vector:
class Cheeses
{
vector<Cheese> v;
public:
void eat()
{
v.erase();
}
// plus other methods which delegate to the contained vector
};

In C or C++, is there a way to extend a class without inheritance?

Is there a way to implement functionality like Class Categories (of Objective-C) or Extension Methods (of C# 3.0) in C and/or C++?
C++ has 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 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");
Not really. It's not the C++ way to treat classes like this.
Amongst others, Meyers argue that it's best to have a small class with the minimal set of operations that make it fully useful. If you want to expand the feature set, you may add an utility namespace (e.g. namespace ClassUtil) that contains non-member utility functions that operate on that minimal class. It's easy to add functions to a namespace from anywhere.
You can check a discussion on the subject here.
C++ doesn't have sealed classes or single class inheritance, so in most cases you can subclass the base class. There are creative ways to make a class non-inheritable, but they are few and far in between. In general, C++ doesn't have the problems C# does that gave birth to extension methods.
C is not Object Orientated, so the question doesn't really apply.
With regard to C#'s extension methods: Not directly. C++ has less need for these things because C++ supports free functions. I've never used Objective-C so I can't comment there.
Can you use an interface? Extension methods are an easy way to avoid subclassing, but they are rendered semi-useless when proper OO techniques are used. The reason that they are used with Linq so much is so that the VS team did not have to go and update code that would most likely break a lot of legacy applications.
Per MSDN:
"In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type."
http://msdn.microsoft.com/en-us/library/bb383977.aspx

How can I use Boost::Python to add a method to an exported class without modifying the base class?

I have a class in C++ that I can't modify. However, that class holds an std::list<> of items that I need to be able to access in a Python extension. Since Boost::Python doesn't seem to have a built-in conversion between an std::list and a Python list, I was hoping to be able to write a method in C++ that could do this conversion for me and later, when I am mapping the C++ classes to Python classes, I could attach this method.
I would prefer if I could just call the method like
baseClassInstance.get_std_list_of_items_as_python_list()
To answer the question in a more general way, you can attach any c++ function that has the right signature to the python export in the class_ declaration.
assume a class foo:
struct foo
{
//class stuff here
}
You can define a free function that takes a reference to foo as the first argument:
int do_things_to_a_foo(foo& self, int a, std::string b, other_type c)
{
//Do things to self
}
And export it just like a member of foo:
class_<foo>("foo")
...
.def("do_things_to_a_foo", &do_things_to_a_foo)
...
;
Boost provides a helper to wrap iterators which is documented here: http://www.boost.org/doc/libs/1_42_0/libs/python/doc/v2/iterator.html
The example hear the end of that page worked for me, you just need to explicitly create the conversion, for example:
class_<std::list<Item> >("ItemList")
.def("__iter__", iterator<std::list<Item> >());
To modify the C++ class without changing it, I am in the habit of creating a thin wrapper that subclasses the real class. This makes a nice place to separate out all the crud that makes my C++ objects feel comfortable from Python.
class Py_BaseClass : public BaseClass {
public:
std::list<Item> & py_get_items();
}

Member functions for derived information in a class

While designing an interface for a class I normally get caught in two minds whether should I provide member functions which can be calculated / derived by using combinations of other member functions. For example:
class DocContainer
{
public:
Doc* getDoc(int index) const;
bool isDocSelected(Doc*) const;
int getDocCount() const;
//Should this method be here???
//This method returns the selected documents in the contrainer (in selectedDocs_out)
void getSelectedDocs(std::vector<Doc*>& selectedDocs_out) const;
};
Should I provide this as a class member function or probably a namespace where I can define this method? Which one is preferred?
In general, you should probably prefer free functions. Think about it from an OOP perspective.
If the function does not need access to any private members, then why should it be given access to them? That's not good for encapsulation. It means more code that may potentially fail when the internals of the class is modified.
It also limits the possible amount of code reuse.
If you wrote the function as something like this:
template <typename T>
bool getSelectedDocs(T& container, std::vector<Doc*>&);
Then the same implementation of getSelectedDocs will work for any class that exposes the required functions, not just your DocContainer.
Of course, if you don't like templates, an interface could be used, and then it'd still work for any class that implemented this interface.
On the other hand, if it is a member function, then it'll only work for this particular class (and possibly derived classes).
The C++ standard library follows the same approach. Consider std::find, for example, which is made a free function for this precise reason. It doesn't need to know the internals of the class it's searching in. It just needs some implementation that fulfills its requirements. Which means that the same find() implementation can work on any container, in the standard library or elsewhere.
Scott Meyers argues for the same thing.
If you don't like it cluttering up your main namespace, you can of course put it into a separate namespace with functionality for this particular class.
I think its fine to have getSelectedDocs as a member function. It's a perfectly reasonable operation for a DocContainer, so makes sense as a member. Member functions should be there to make the class useful. They don't need to satisfy some sort of minimality requirement.
One disadvantage to moving it outside the class is that people will have to look in two places when the try to figure out how to use a DocContainer: they need to look in the class and also in the utility namespace.
The STL has basically aimed for small interfaces, so in your case, if and only if getSelectedDocs can be implemented more efficiently than a combination of isDocSelected and getDoc it would be implemented as a member function.
This technique may not be applicable anywhere but it's a good rule of thumbs to prevent clutter in interfaces.
I agree with the answers from Konrad and jalf. Unless there is a significant benefit from having "getSelectedDocs" then it clutters the interface of DocContainer.
Adding this member triggers my smelly code sensor. DocContainer is obviously a container so why not use iterators to scan over individual documents?
class DocContainer
{
public:
iterator begin ();
iterator end ();
// ...
bool isDocSelected (Doc *) const;
};
Then, use a functor that creates the vector of documents as it needs to:
typedef std::vector <Doc*> DocVector;
class IsDocSelected {
public:
IsDocSelected (DocContainer const & docs, DocVector & results)
: docs (docs)
, results (results)
{}
void operator()(Doc & doc) const
{
if (docs.isDocSelected (&doc))
{
results.push_back (&doc);
}
}
private:
DocContainer const & docs;
DocVector & results;
};
void foo (DocContainer & docs)
{
DocVector results;
std :: for_each (docs.begin ()
, docs.end ()
, IsDocSelected (docs, results));
}
This is a bit more verbose (at least until we have lambdas), but an advantage to this kind of approach is that the specific type of filtering is not coupled with the DocContainer class. In the future, if you need a new list of documents that are "NotSelected" there is no need to change the interface to DocContainer, you just write a new "IsDocNotSelected" class.
The answer is proabably "it depends"...
If the class is part of a public interface to a library that will be used by many different callers then there's a good argument for providing a multitude of functionality to make it easy to use, including some duplication and/or crossover. However, if the class is only being used by a single upstream caller then it probably doesn't make sense to provide multiple ways to achieve the same thing. Remember that all the code in the interface has to be tested and documented, so there is always a cost to adding that one last bit of functionality.
I think this is perfectly valid if the method:
fits in the class responsibilities
is not too specific to a small part of the class clients (like at least 20%)
This is especially true if the method contains complex logic/computation that would be more expensive to maintain in many places than only in the class.