I have two classes, ClassWorking and TemplateClass, they are not related in any way.
Is there a way to say, I want the function TemplateGenerate() from my TemplateClass now to behave like the function generate() from my class ClassWorking.
Like a (this function does not exist) SetFunctionBehavior(&templateClassRef->templateGenerate, &classWorkingRef->generate)
I know I can use function pointer to make TemplateClass receive a pointer and call it in the class, but that not what I want.
It's more something like a LD_Preload, to replace the inner of function without having to re-write it and without inherit from a class who has it.
to be a little more explicit let's see it more like a node construction for class
TemplateClass can have multiple functions but not with the same behaviour
- TemplateClass
- TemplateGenerate() {will do this}
- TemplateGenerate() {will do that}
- TemplateGenerate() {will do like that}
and when I declare my class pointer templateClassRef->TemplateGenerate = TemplateGenerate() {will do that}
but not with a lambda :)
The point is to have something really generic without having to re-create a class for each need, for example I could have a class:
TemplateGenerate
- function A {A1 Behavior} Functiun B {B1 Behavoir} Functiun C {C1 Behavior}
{A2 Behavior} {B2 Behavoir} {C2 Behavior}
{A3 Behavior} {B3 Behavoir} {C3 Behavior}
And when I declare my function I say I take A1,B2,C3 or A1,B1,C2
The method ClassWorking::generate is a function that takes a ClassWorking and does stuff.
A function that has the same behaviour also takes a ClassWorking. That is part of what the function does.
As TemplateClass is unrelated to ClassWorking, a method TemplateClass::templateGenerate that "behaves alike" ClassWorking::generate cannot succeed; you don't have a ClassWorking, so one of the prequisites of ClassWorking::generate isn't being fullfilled.
Now, it might be the case that the implementation of ClassWorking::generate doesn't actually need an instance of ClassWorking. It might need something else.
But for the compiler to know this, you have to change the method from being a method of ClassWorking to being something else. For example, you could write a free function generate that takes an argument what you actually need, and have ClassWorking::generate call that free function.
Then calling the free function generate from a stub method TemplateClass::templateGenerate becomes trivial.
C++ does not support "do what I mean" or "read my mind". You actually have to tell the compiler what you want to happen. And types matter in C++, so you cannot wire up a method on one class to another class without also telling C++ how the types relate.
There are languages where types are looser and you actually can grab a method off one class and glue it onto another. These are generally interpreted languages with much heavier runtime object models than C++; members in this language are implemented as property bags of named values, values are actually variants at runtime, etc.
You can implement that kind of object in C++, but it isn't a "native" C++ object, and you'll have to write a pile of glue code (some of which could be hidden by metaprogramming). That is far from a beginner task, and usually a bad idea; if you need the flexibility of scripting languages, just use a scripting language.
One way is to use composition. Define an interface
struct Interface
{
virtual void/*maybe*/ templateGenerate(/*maybe*/) /*const?*/ = 0;
};
Then implement
struct ClassWorkingImpl : Interface, ClassWorking
{
// ToDo - delegate all the constructors
// ToDo - implement templateGenerate using the method in ClassWorking
};
and similarly for TemplateClass.
Then you instantiate ClassWorkingImpl &c. rather than ClassWorking. And you can call the interface method templateGenerate on either.
Related
I would like to write down a set of classes in which there are:
a pure virtual class that wraps an object of any kind and the relate getter for it.
one or more classes for every kind of object I need, extending the virtual one and overriding the getter in order to specialize it.
A template class solution for the wrapper seems to fit the case but I have to use it in two different contexts:
the first one is not aware of wrapper implementations. In this case I should declare a Wrapper<AnyObj> var; with AnyObj standing for any class name (like ? in Java). As far as I know, you can't do this in c++.
the second one is restricted to a particular wrapper implementation. In this case I need the getter to return the wrapped object with the exact type (rather than downcasting it).
If I'm right I cannot use a template class and, moreover, the wrapper won't have a protected: T* wrappedObject member.
I don't know if I'm stuck in the Java approach, wrongly thinking from the beginning, or missing something.
Any suggestion is appreciated.
I am after your opinion on how best to implement an inheritance pattern in C++. I have two base classes, say
class fooBase{
protected:
barBase* b;
};
class barBase{};
where fooBase has a barBase. I intend to put these classes in a library, so that wherever I have a fooBase it can use its barBase member.
I now intend to create a specialisation of these in a specific program
class fooSpec : public fooBase{};
class barSpec : public barBase{};
Now I want fooSpec::b to point to a barSpec instead of a barBase. I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
Is there another way that this is often acheived?
Cheers.
Create a method in your specclass to cast the b into the special version.
That way instead of casting it all the time, it looks like a getter.
On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.
You may consider the template solution:
template <class T>
class fooBase{
protected:
T* b;
};
and then use it as
class fooSpec : public fooBase<barSpec>{};
while ordinarily, the base would be used as fooBase<barBase>.
Is this what you want?
Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.
Now I want fooSpec::b to point to a barSpec instead of a barBase.
There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.
I know that I can just initialise b with a new barSpec, but this would
require me to cast the pointer to a barSpec whenever I wanted to use
specific functions in the specialisation wouldn't it?
Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.
Is there another way that this is often acheived?
Not that I'm aware of.
this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
That depends on whether the method you are trying to invoke is defined in the superclass and whether it is virtual.
You need to cast the pointer before invoking a method if one of the following is true...
The method belongs to the subclass only
The superclass has an implementation of the method and the subclass's implementation does not override the implementation in the superclass. This amounts to a question of whether the function is a virtual function.
Avoid data members in non-leaf classes, use pure virtual getters instead. If you follow this simple rule, your problem solves itself automatically.
This also makes most non-leaf classes automatically abstract, which may seem like an undue burden at first, but you get used to it and eventually realize it's a Good Thing.
Like most rules, this one is not absolute and needs to be broken now and then, but in general it's a good rule to follow. Give it a try.
If it looks too extreme, you may try one of the design patterns that deal with dual hierarchies such as Stairway to Heaven.
I have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.
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
};
This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.