I'm working with boost on a project and I would like to use the Bundled Properties mechanism on a class Foo. This is to allow the user to add data like a struct to the class.
Actually, Foo is a class used in similar ways to the edges on a graph in the Boost Graph Library. Foo needs to contains user defined datas (tags, IDs, ...) that the user can handle through visitors during algorithms process for example.
However I was not able to understand how to add this capability to my class Foo with meta programming. Could you explain me some design patterns to do that ?
The idea behind this is simple.
The hosting class take as a template parameter the hosted one.
Once it has it, it just derive from the latter:
template <class T>
template class Host : public T
{
};
As the rules of inheritance specifies, all public members are accessible from the deriven class.
If you want to chain more properties, use multiply inheritance.
Simple and awesome, right?
Related
I hesitate to ask this question, because it's deceitfully simple one. Except I fail to see a solution.
I recently made an attempt to write a simple program that would be somewhat oblivious to what engine renders its UI.
Everything looks great on paper, but in fact, theory did not get me far.
Assume my tool cares to have an IWindow with IContainer that hosts an ILabel and IButton. That's 4 UI elements. Abstacting each one of these is a trivial task. I can create each of these elements with Qt, Gtk, motif - you name it.
I understand that in order for implementation (say, QtWindow with QtContainer) to work, the abstraction (IWindow along with IContainer) have to work, too: IWindow needs to be able to accept IContainer as its child: That requires either that
I can add any of the UI elements to container, or
all the UI elements inherit from a single parent
That is theory which perfectly solves the abstraction issue. Practice (or implementation) is a whole other story. In order to make implementation to work along with abstraction - the way I see it I can either
pollute the abstraction with ugly calls exposing the implementation (or giving hints about it) - killing the concept of abstraction, or
add casting from the abstraction to something that the implementation understands (dynamic_cast<>()).
add a global map pool of ISomething instances to UI specific elements (map<IElement*, QtElement*>()) which would be somewhat like casting, except done by myself.
All of these look ugly. I fail to see other alternatives here - is this where data abstraction concept actually fails? Is casting the only alternative here?
Edit
I have spent some time trying to come up with optimal solution and it seems that this is something that just can't be simply done with C++. Not without casting, and not with templates as they are.
The solution that I eventually came up with (after messing a lot with interfaces and how these are defined) looks as follows:
1. There needs to be a parametrized base interface that defines the calls
The base interface (let's call it TContainerBase for Containers and TElementBase for elements) specifies methods that are expected to be implemented by containers or elements. That part is simple.
The definition would need to look something along these lines:
template <typename Parent>
class TElementBase : public Parent {
virtual void DoSomething() = 0;
};
template <typename Parent>
class TContainerBase : public Parent {
virtual void AddElement(TElementBase<Parent>* element) = 0;
};
2. There needs to be a template that specifies inheritance.
That is where the first stage of separation (engine vs ui) comes. At this point it just wouldn't matter what type of backend is driving the rendering. And here's the interesting part: as I think about it, the only language successfully implementing this is Java. The template would have to look something along these lines:
General:
template<typename Engine>
class TContainer : public TContainerBase<Parent> {
void AddElement(TElementBase<Parent>* element) {
// ...
}
};
template<typename Engine>
class TElement : public TElementBase<Parent> {
void DoSomething() {
// ...
}
};
3. UI needs to be able to accept just TContainers or TElements
that is, it would have to ignore what these elements derive from. That's the second stage of separation; after all everything it cares about is the TElementBase and TContainerBase interfaces. In Java that has been solved with introduction of question mark. In my case, I could simply use in my UI:
TContainer<?> some_container;
TElement<?> some_element;
container.AddElement(&element);
There's no issues with virtual function calls in vtable, as they are exactly where the compiler would expect them to be. The only issue would be here ensuring that the template parameters are same in both cases. Assuming the backend is a single library - that would work just fine.
The three above steps would allow me to write my code disregarding backend entirely (and safely), while backends could implement just about anything there was a need for.
I tried this approach and it turns to be pretty sane. The only limitation was the compiler. Instantiating class and casting them back and forth here is counter-intuitive, but, unfortunately, necessary, mostly because with template inheritance you can't extract just the base class itself, that is, you can't say any of:
class IContainerBase {};
template <typename Parent>
class TContainerBase : public (IContainerBase : public Parent) {}
nor
class IContainerBase {};
template <typename Parent>
typedef class IContainerBase : public Parent TContainerBase;
(note that in all the above solutions it feels perfectly natural and sane just to rely on TElementBase and TContainerBase - and the generated code works perfectly fine if you cast TElementBase<Foo> to TElementBase<Bar> - so it's just language limitation).
Anyway, these final statements (typedef of class A inheriting from B and class X having base class A inheriting from B) are just rubbish in C++ (and would make the language harder than it already is), hence the only way out is to follow one of the supplied solutions, which I'm very grateful for.
Thank you for all help.
You're trying to use Object Orientation here. OO has a particular method of achieving generic code: by type erasure. The IWindow base class interface erases the exact type, which in your example would be a QtWindow. In C++ you can get back some erased type information via RTTI, i.e. dynamic_cast.
However, in C++ you can also use templates. Don't implement IWindow and QtWindow, but implement Window<Qt>. This allows you to state that Container<Foo> accepts a Window<Foo> for any possible Foo window library. The compiler will enforce this.
If I understand your question correctly, this is the kind of situation the Abstract Factory Pattern is intended to address.
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the theme. The client doesn't know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.
Creating a wrapper capable of abstracting libraries like Qt and Gtk doesn't seems a trivial tasks to me. But talking more generally about your design problem, maybe you could use templates to do the mapping between the abstract interface and a specific implementation. For example:
Abstract interface IWidget.h
template<typename BackendT>
class IWidget
{
public:
void doSomething()
{
backend.doSomething();
}
private:
BackendT backend;
};
Qt implementation QtWidget.h:
class QtWidget
{
public:
void doSomething()
{
// qt specifics here
cout << "qt widget" << endl;
}
};
Gtk implementation GtkWidget.h:
class GtkWidget
{
public:
void doSomething()
{
// gtk specifics here
cout << "gtk widget" << endl;
}
};
Qt backend QtBackend.h:
#include "QtWidget.h"
// include all the other gtk classes you implemented...
#include "IWidget.h"
typedef IWidget<QtWidget> Widget;
// map all the other classes...
Gtk backend GtkBackend.h:
#include "GtkWidget.h"
// include all the other gtk classes you implemented...
#include "IWidget.h"
typedef IWidget<GtkWidget> Widget;
// map all the other classes...
Application:
// Choose the backend here:
#include "QtBackend.h"
int main()
{
Widget* w = new Widget();
w->doSomething();
return 0;
}
This is a narrower version of the question put on hold due to being too broad.
On pages 6-7 of Modern C++ Design, Andrei Alexandrescu lists three ways in which the multiple inheritance is weaker than templates with respect to building flexible designs. In particular, he states that the mechanics provided by multiple inheritance is poor (the text in square brackets and formatting are mine as per my understanding of the context):
In such a setting [i.e. multiple inheritance], [to build a flexible SmartPtr,] the user would build a multithreaded, reference-counted smart pointer class by inheriting some BaseSmartPtr class and two classes: MultiThreaded and RefCounted. Any experienced class designer knows
that such a naïve design does not work.
...
Mechanics. There is no boilerplate code to assemble the inherited components in a controlled
manner. The only tool that combines BaseSmartPtr, MultiThreaded, and RefCounted
is a language mechanism called multiple inheritance. The language applies
simple superposition in combining the base classes and establishes a set of simple rules
for accessing their members. This is unacceptable except for the simplest cases. Most
of the time, you need to orchestrate the workings of the inherited classes carefully to
obtain the desired behavior.
When using multiple inheritance, one can achieve some pretty flexible orchestration by writing member functions that call member functions of several base classes. So, what is the orchestration that is missing from multiple inheritance and present in templates?
Please note that not every disadvantage of multiple inheritance compared to templates goes as an answer here, but only a disadvantage in what Andei calls mechanics in the above quote. In particular, please make sure that you are not talking about one of the other two weaknesses of multiple inheritance listed by Andrei:
Type information. The base classes do not have enough type information to carry on
their tasks. For example, imagine you try to implement deep copy for your smart
pointer class by deriving from a DeepCopy base class. But what interface would DeepCopy
have? It must create objects of a type it doesn’t know yet.
State manipulation. Various behavioral aspects implemented with base classes must manipulate
the same state. This means that they must use virtual inheritance to inherit a
base class that holds the state. This complicates the design and makes it more rigid because
the premise was that user classes inherit library classes, not vice versa.
I think that what Alexandrescu is referring to in the "Mechanics" paragraph is expounded upon in the rest of the chapter. He's referring to how much more flexible policy-based class design is than inheritance-based class design, particularly with respect to the various ways in which policies can be implemented and combined - this in comparison to the single implementation and combination allowed through multiple inheritance.
For instance, when discussing the Creator policy he points out that the policy requires only a Create() method that returns a pointer to the class being created, but doesn't specify that it be virtual or non-static. And he shows several ways in which each policy could be created: a straightforward policy class such as (from section 1.5, skipping the MallocCreator and PrototypeCreator policies)
template<class T>
struct OpNewCreator
{
static T* Create()
{
return new T;
}
};
...
> //Library code
> template <class CreationPolicy>
> class WidgetManager:public CreationPolicy
> {
> ...
> };
...
// Application Code
typedef WidgetManager<OpNewCreator<Widget> > MyWidgetMgr;
or it could be implemented with template template parameters (section 1.5.1) as
//Library Code
template <template <class> class Creation Policy>
class WidgetManager : public CreationPolicy <Widget>
{
...
}
// Application Code
typedef WidgetManager<OpNewCreator> MyWidgetMgr
or (section 1.5.2) - implemented as a template member function:
struct OpNewCreator
{
template <class T>
static T* Create()
{
return new T;
}
}
These are examples of the flexible mechanics that are available in a template-based policy class solution and not available in a multiple inheritance solution. These particular examples are not maybe all that exciting, probably because they have to be short and simple for pedagogical reasons.
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.
I have a situation: In a single Solution I have two Projects. I need to extend the Class:Foo used in Project:A so that I can add new functionality required in Project:B without changing its name. Problem is: Class:Foo already contains (i.e. has a) Class:Bar and is contained by Class:Goo in both Project:A & Project:B. In Project:B I am inheriting Class:Goo into Class:Goo_Ex; but I need to also extend both: Class:Foo and Class:Bar with companion functions.
To make it more clear - I could accomplish this using the following crude method:
/* Project:A-Class:Foo */
class Foo
{
.
.
.
# ifdef PROJECT_B
fnExtended();
# endif
};
but that would litter my code in Project:A.
A possible solution that I can think of is to use Inheritance and have Class:Foo_Global Inherited-[Only] as Class:Foo in Project:A and Inherited-[Extend] as, again, Class:Foo in Project:B; same for Class:Bar. But is their a more straight forward solution..?
I think your proposed solution (to hide the current Foo as some other class name and inherit from it in a new Foo class in both projects) is how you should do it.
This is a really abstract problem, and it's difficult to give you a good specific solution without more details.
The basic way of handling this is inheritance. But this requires some pre-planning. It means that when you refer to Foo in project A, you should use pointers or references. If you create a Foo (and need code from project A create Foo_Extended when it's part of project B) then you need to have a configurable Foo factory that will create objects of the appropriate type depending upon context.
The other way of handling this is templates. You never have the code in project A refer directly to the global Foo class. Instead it always refers to a template parameter. In project A that template parameter will end up resolving to Foo, and in project B it will resolve to some other class that has the needed functionality.
These are the two general ways of handling this issue in C++. And which you use depends a lot on the details of the context in which you're using them.
The way to extend you class is not to extend it! Just use a function taking suitable arguments instead.
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.