I have a large set classes which I need to "wrap" in a very thin subclass. The functionality of the base classes doesn't change, and their interface remains intact.
The problem is, that in order to use the base classes's constructors (and most of them have more than one), I need to decalre an identical constructor in each of the subclasses, and simply pass the parameters over to the constructor of the base class (99% of the time I have nothing else to do upon construction). That's a lot of pointless work.
What's the easiest way to do this?
Edit: Even if it's not natively supported in the language, maybe there's some tool that can auto-generate that code?
You could add templated constructors for all possible parameters to your wrapper class:
template<class Base>
class wrapper : public Base {
public:
wrapper() : Base() {}
template<typename T1>
wrapper(T1 a1) : Base(a1) {}
template<typename T1, typename T2>
wrapper(T1 a1, T2 a2) : Base(a1, a2) {}
// ...
};
Since the templates will not be instantiated for constructors that aren't called it doesn't matter if these other constructors would be invalid. Only the constructors that are actually used need to exist in the base class:
class A {
public:
A(int a) {};
};
int main() {
wrapper<A> aw(1);
return 0;
}
Probably there are some corner cases where this approach will lead to problems, but for simple cases it works.
I think you're out of luck unless you can use C++0x. Read this article:
Automatic creation of constructor, based on parent class' constructor (C++)
Wishful thinking leads me to suggest
class BaseClass {
public:
BaseClass(foo, bar, baz);
};
template <class T>
class BaseInheritor : public BaseClass {
public:
T(foor, bar, baz);
};
class Child : public BaseInheritor<Child> {
// Other stuff
};
I don't think C++ templates can quite do what I've just written, unfortunately. There's a pretty straightforward answer with macros, but I feel dirty suggesting it:
#define CHILD_CLASS_DEFAULT(name) \
class name : public BaseClass { \
public: name(foo, bar, baz) : BaseClass(foo, bar, baz) { } \
private:
#define CHILD_CLASS_OVERRIDE(name) \
class name : public BaseClass { \
I'd go for a script-based solution, maybe based on gccxml or something similar.
With that you could write a simple script (i.e. generate-derivate <input-file> <base-name> <derivative-name> <output-file>) that generates you the wrapper. You'd only have to make changes manually if you are adding/changing functionality.
edit: vague outline:
write derivative-name + " : public " + base-name + " {\npublic:\n"
foreach <Constructor> where attribute name == base-name
write "\tderivate-name("
foreach <Argument>
resolve by attribute type (query FundamentalType, ReferenceType, ...)
write argument type etc.
write ");\n"
write "\n};\n"
It all depends on what script language and what xml tools you use. Trolltech has XQuerys in their example.
Related
Sorry for my poor english I'll try to do my best.
I want to design an interface that should be used like this:
class MyObject : public IMyInterface<MyObject>
{
// ...
};
The interface could look like this:
template <class _TMyObject>
class IMyInterface
{
virtual _TMyObject* Get() = 0;
};
What i'm looking after, is a way to verify, at compile time, that the interface is used as intended.
How can I test if _TMyObject "is-a" IMyInterface<_TMyObject>? Inside the interface definition, with a static_assert for example.
Thanks for any help :).
Have a nice day!
You can't put static_assert inside the class itself, because D is an incomplete type, but you can put it in the destructor (or constructor, but there can be many constructors):
template<class D>
struct B
{
~B()
{
static_assert(std::is_base_of_v<B, D>);
};
};
struct Not_E {};
struct D : B<D> { };
struct E : B<Not_E> { };
void foo()
{
D d; // OK
E e; // Fails
}
Addition. Note that this solution is not a complete protection against incorrect usage of CRTP. Please refer to Some Programmer Dude's answer for a nice example of error that can't be caught by it.
Since C++11 there are many type property traits that could be used to do checks at compile-time.
For example std::is_base_of which in your case could be used like perhaps
template<typename TChild>
struct IMyInterface
{
static_assert(std::is_base_of<IMyInterface, TChild>::value, "Derived class not derived from IMyInterface");
// ...
};
Note: The exact code shown above will not work directly, but rather show the principle.
Of course, that do allow something like
class MyFirstClass : public IMyInterface<MyFirstClass>
{
// ...
};
// Note wrong class in template
// vvvvvvvvvvvv
class MySecondClass : public IMyInterface<MyFirstClass>
{
// ...
};
So to answer your question if it's possible for such a check: Not really the way you want. Even using other traits and meta-programming, you can never guarantee that the template argument for the interface class is "correct" when used in the CRTP.
The only way I can see it work is by using down-casting at run-time with dynamic_cast, something like dynamic_cast<TChild*>(this) != nullptr in the interface class.
I have some issues to find a relevant solution to my problem.
I have to return some data from a class, and the type of data kind of depends on the class.
My first solution was this :
class Base
{
virtual QVector<Data*> getData() const = 0;
};
class Derived : public Base
{
virtual QVector<DerviedData*> getData() const = 0;
};
But I know this is impossible, even if DerivedData extends Data, because of invalid covariant return types.
So I came up with another idea which implies template. What I did is I turned the Base class into a template class :
template<class T>
class Base
{
virtual QVector<T*> getData() const = 0;
}
And then I could write a Derivedconstructor like that :
Derived::Derived() : Base<DerivedData>() {}
But know I have another problem. Suppose that I write another class, which has a method taking any Base class in parameters.
void Foo::doSomething(Base* b) {
b->getData();
}
This does not compile and says
invalid use of template-name 'Base' without an argument list
which I understand perfectly.
Supposing that my code will look like that :
DerivedClass1 d1;
DerivedClass2 d2;
DerivedClass3 d3;
this->doSomething(&d1);
this->doSomething(&d2);
this->doSomething(&d3);
What are my solutions here ? May I do something like "templating" the method doSomething ?
this->doSomething<DerivedData>(&d1);
With a protoype like
template<class T>
void doSomething(Base<T>* b);
Is that possible ? Is that a good way of thinking ?
Coming from Java, I used to resolve such problems by using wildcards
abstract List<? extends Data> getData();
But I heard there is stricly speaking no such things in C++ (more or less simulable with such things as std::is_base_of).
Thank you for your time.
You can let Derived::getData() return QVector<Data*>. When you need to use it, find out if the pointers in QVector is to Data or DerivedData, using dynamic_cast or similar method.
I have a class A, which is an external class and not under my control, but i can design the specs of it.
In my code, I want to attach statically some properties and methods to A. I could inherit from A and attach the new functionality. But, since i don't know the exact specs of A, I cannot provide the constructors of A in my derived class internalA.
I could use the decorator pattern, but it seems a bit overkill since i want to decorate at build time.
Any suggestion to solve it nicely ?
may be perfect forwarding and varadic templates will help:
#include <utility>
#include "A.h"
class B: public A
{
public:
template<class... TT>
B(TT&&... tt) :A(std::forward<TT>(tt)...) {}
B(const B&)=default;
B(B&&)=default;
//whatever other decoration
};
If you prefer composition, the pattern works the same, simply A will be a member and not a base.
I believe a reference to the externalA should be sufficient.
template <typename A>
class InternalA {
A &externalA;
int property1;
std::string property2;
//...
public:
InternalA (A &extA, int prop1, std::string prop2 /*...*/);
// accessors to properties and to externalA...
};
But, I may have misunderstood your question.
I'm trying to create a vector (or any STL container, really) that could hold a set of various objects that are subclasses of one specific type. The problem is that my base class is templated.
From what I can tell, I have to create an interface/abstract super base class (not sure what the preferred C++ terminology is). I'd prefer not to do this, and just use my (templated) abstract base class. Below is some example code.
Basically, is there a way not to require the WidgetInterface? Someway to tell the compiler to ignore template requirements? If I must have WidgetInterface, am I going the right way with the following?
#include <vector>
#include "stdio.h"
enum SomeEnum{
LOW = 0,
HIGH = 112358
};
// Would like to remove this WidgetInterface
class WidgetInterface{
public:
// have to define this so we can call it while iterating
// (would remove from Widget if ended up using this SuperWidget
// non-template baseclass method)
virtual void method() = 0;
};
template <class TDataType>
class AbstractWidget : public WidgetInterface{
public:
TDataType mData;
virtual void method() = 0;
// ... bunch of helper methods etc
};
class EnumWidget : public AbstractWidget<SomeEnum>{
public:
EnumWidget(){
mData = HIGH;
}
void method(){
printf("%d\n", mData); // sprintf for simplicity
}
};
class IntWidget : public AbstractWidget<int>{
public:
IntWidget(){
mData = -1;
}
void method(){
printf("%d\n", mData); // sprintf for simplicity
}
};
int main(){
// this compiles but isn't a workable solution, not generic enough
std::vector< AbstractWidget<int>* > widgets1;
// only way to do store abitary subclasses?
std::vector<WidgetInterface*> widgets2;
widgets2.push_back(new EnumWidget());
widgets2.push_back(new IntWidget());
for(std::vector<WidgetInterface*>::iterator iter = widgets2.begin();
iter != widgets2.end(); iter++){
(*iter)->method();
}
// This is what i'd _like_ to do, without needing WidgetInterface
// std::vector< AbstractWidget* > widgets3;
return 0;
}
No, you can't use directly AbstractWidget as a parameter of STL container or anything else.
The reason is that class AbstractWidget does not exist. It is only a template for compiler to construct classes from.
What exists is AbstractWidget<SomeEnum> and AbstractWidget<int> only because of EnumWidget and IntWidget inheriting from them.
Templates exist at compiler-level only. If AbstractWidget<T> weren't used anywhere in your code, there would be no traces of it during the runtime.
Therefore, the code you posted seems to be the best (if not only) solution for your problem.
What you've done is the solution: you need a common class/interface, and since AbstractWidget is class template, therefore it cannot be used as common class for all concrete classes for which the template argument is different. So I think, you should go with this class design. It seems to be quite reasonable solution.
In fact the classes AbstractWidget<int> and AbstractWidget<double> are different classes, so your class IntWidget is a subclass of the first but is in no relation with the second. You need to have a common parent class to put in the vector so unfortunately you can not avoid the common interface that is not templated.
This could be completely in the wrong direction, but could you do something like this:
template <class T>
class ConcreteWidget : public AbstractWidget<T>
{
};
and then use template specialization to define your specific widgets like this:
template <>
class ConcreteWidget : public AbstractWidget<int>
{
public:
ConcreteWidget() : mData(-1) {}
};
template <>
class ConcreteWidget : public AbstractWidget<SomeEnum>
{
public:
ConcreteWidget() : mData(HIGH) {}
};
So rather than having an IntWidget and an EnumWidget, you'd have a ConcreteWidget and ConcreteWidget and then could simply have a vector<WidgetInterface> that would be the super of all of these generic children?
I'm not sure if this solves your problem, or would even work. I'd love feedback on this answer.
There was an interesting problem in C++, but it was more about architecture.
There are many (10, 20, 40, etc) classes describing some characteristics (mix-in classes), for example:
struct Base { virtual ~Base() {} };
struct A : virtual public Base { int size; };
struct B : virtual public Base { float x, y; };
struct C : virtual public Base { bool some_bool_state; };
struct D : virtual public Base { string str; }
// ....
The primary module declares and exports a function (for simplicity just function declarations without classes):
// .h file
void operate(Base *pBase);
// .cpp file
void operate(Base *pBase)
{
// ....
}
Any other module can have code like this:
#include "mixing.h"
#include "primary.h"
class obj1_t : public A, public C, public D {};
class obj2_t : public B, public D {};
// ...
void Pass()
{
obj1_t obj1;
obj2_t obj2;
operate(&obj1);
operate(&obj2);
}
The question is how do you know what the real type of a given object in operate() is without using dynamic_cast and any type information in classes (constants, etc)? The operate() function is used with a big array of objects in small time periods and dynamic_cast is too slow for it and I don't want to include constants (enum obj_type { ... }) because this is not the OOP-way.
// module operate.cpp
void some_operate(Base *pBase)
{
processA(pBase);
processB(pBase);
}
void processA(A *pA)
{
}
void processB(B *pB)
{
}
I cannot directly pass a pBase to these functions. And it's impossible to have all possible combinations of classes, because I can add new classes just by including new header files.
One solution that came to mind, in the editor I can use a composite container:
struct CompositeObject
{
vector<Base *pBase> parts;
};
But the editor does not need time optimization and can use dynamic_cast for parts to determine the exact type. In operate() I cannot use this solution.
So, is it possible to avoid using a dynamic_cast and type information to solve this problem? Or maybe I should use another architecture?
The real problem here is about what you are trying to achieve.
Do you want something like:
void operate(A-B& ) { operateA(); operateB(); }
// OR
void operate(A-B& ) { operateAB(); }
That is, do you want to apply an operation on each subcomponent (independently), or do you wish to be able to apply operations depending on the combination of components (much harder).
I'll take the first approach here.
1. Virtual ?
class Base { public: virtual void operate() = 0; };
class A: virtual public Base { public virtual void operate() = 0; };
void A::operate() { ++size; } // yes, it's possible to define a pure virtual
class obj1_t: public A, public B
{
public:
virtual void operate() { A::operate(); B::operate(); }
};
Some more work, for sure. Notably I don't like the repetition much. But that's one call to the _vtable, so it should be one of the fastest solution!
2. Composite Pattern
That would probably be the more natural thing here.
Note that you can perfectly use a template version of the pattern in C++!
template <class T1, class T2, class T3>
class BaseT: public Base, private T1, private T2, private T3
{
public:
void operate() { T1::operate(); T2::operate(); T3::operate(); }
};
class obj1_t: public BaseT<A,B,C> {};
Advantages:
no more need to repeat yourself! write operate once and for all (baring variadic...)
only 1 virtual call, no more virtual inheritance, so even more efficient that before
A, B and C can be of arbitrary type, they should not inherit from Base at all
edit the operate method of A, B and C may be inlined now that it's not virtual
Disadvantage:
Some more work on the framework if you don't have access to variadic templates yet, but it's feasible within a couple dozen of lines.
First thing that comes to mind is asking what you really want to achieve... but then again the second thought is that you can use the visitor pattern. Runtime type information will implicitly be used to determine at what point in the hierarchy is the final overrider of the accept method, but you will not explicitly use that information (your code will not show any dynamic_cast, type_info, constants...)
Then again, my first thought comes back... since you are asking about the appropriateness of the architecture, what is it that you really want to achieve? --without knowledge of the problem you will only find generic answers as this one.
The usual object oriented way would be to have (pure) virtual functions in the base class that are called in operate() and that get overridden in the derived classes to execute code specific to that derived class.
Your problem is that you want to decide what to do based on more than one object's type. Virtual functions do this for one object (the one left of the . or ->) only. Doing so for more than one object is called multiple dispatch (for two objects it's also called double dispatch), and in C++ there's no built-in feature to deal with this.
Look at double dispatch, especially as done in the visitor pattern.