Using an interface, and telling it all implementors _will also_ inherit from a common base class - c++

Sometimes, you invent an interface to say that a certain type of object supports a certain type of behavior. For example, both Dog and ScaryDog have the MeleeAttacker interface.
But now say I pass a MeleeAttacker* into some function,
void Attack( MeleeAttacker* attacker, Living *victim ) ;
Because MeleeAttacker is separated from the hierarchy, I can't access the vitals of attacker -- I cannot access members of Living for attacker even though I know attacker is a Living. Because of how I constructed the hierarchy, I know that MeleeAttackers will always be inheritors of the common class WarmBlooded. But the code doesn't know that. My question is, how can I tell the code that?
I think I have just confused things by introducing the MeleeAttacker interface, but I didn't want to crowd the base WarmBlooded class with functions that won't be implemented in some branches of the hierarchy (for example, the "implementation" for a Bird's melee attack might be {} (nothing)).

Why not simply cast your argument to a Living * using dyanmic_cast? You know it will, since you guarantee that by virtue of your concrete classes implementing the latter whenever the former is implemented.
Basically the idea is kind-of-like queryInterface in COM, only you don't have to actually implement queryInterface yourself in each class, since you know the cast will work, and you don't have to implement graceful handling in your calling code, since, again, you know the cast will succeed.

Related

OOP Design Player and AI Controlled Unit. dynamic_cast?

Lets say I have a Actor type, which can be any placeable object on my Game Level.
I also have Unit which is a child class of Actor. A Unit can be either a player or a AI controlled hero.
And Unit also got 2 child classes: Player (the player) and Hero (AI controlled unit).
In the Unit class, there will be movement info, rotation, and other general settings which will be needed for both Player and Hero. In the child classes AI will have different and more functions than the player.
Right now I'm facing the following problem:
A function only accepts Actor as parameter (e.g. OnOverlap(Actor a*))
but OnOverlap() should only do something if it is a Unit class (hero or player).
Therefore I would need something like instanceof() from Java in C++.
A workaround would be either to use dynamic_cast, but I'm not sure if thats a good idea for performance. Or use virtual, but this won't work when Hero has more functions than Player.
Or should I attempt a whole new OOP design?
I'd say that a dynamic_cast is code smell. Not necessary bad per se, but a sign that something might be going wrong with your design.
One of the important concepts in OOP is polymorphism: the idea that objects behave differently depending on their type, and that this behavior is encapsulated, hidden behind an interface. If you explicitely check the type of an object to change the logic you want to apply to it, then you're violating polymorphism.
Now virtual methods aren't that great either, they indeed incur runtime costs, and can sometimes bring too much complexity to the table. C++ makes virtual methods the exception, not the default, I believe for these very reasons.
One thing you should know is that virtual methods are only one kind of polymorphism, called dynamic polymorphism. There's another way to get different behaviors depending on a type that is less impeding for the runtime: static polymorphism, AKA template metaprogramming. But this isn't really helping on the complexity side.
Now what you really should do in this case is treat separate things separately. You probably want to have this OnOverlap() method on Units for a reason: let's say you're doing collision check on Units only, not all Actors. Then maintain a separate list of Units, and have that OnOverlap() method non-virtual on the Unit class. Thinking this way is often key.
This technique is called Run-Time Type Information (RTTI), and checking if the output of a dynamic_cast is NULL is a valid implementation.
Another method is to #include <typeinfo> and use typeid(*a).name() to get the string name of a's type.
The need to use dynamic_cast is often (though not always) a sign that you have a design flaw. In this case, I think you do.
Without further comment on the overall design of the architecture you've described, I would say using virtual methods is the right approach. Have OnOverlap takes it's actor and call an OnOverlapped method on the actor, perhaps giving it a pointer to the thing executing the initial OnOverlap method (it's not clear from your question what that is(*)).
void X::OnOverlap (Actor * actor) {
actor->OnOverlapped(this);
}
OnOverlapped is itself virtual. This allows you to "do the right thing" in the case of an actor unit, but do nothing or some other default behavior everywhere else. You are correct that in this case that means you can only work with the public API of Actor. You'd have to move anything requiring Player's additional methods into the Player implementation of OnOverlapped. If you really think you cannot do that for some reason, you should perhaps consider an alternative design at a higher level (and may need to edit your question to provide more details about your architecture).
(*) My initial read of your question made me think OnOverlap is not a method of Actor already; that it was part of something unrelated. If it is part of Actor, you may be instead interested in a pattern called double dispatch, which can be used for this sort of "collision handling" type of problem, and is also a technique using dynamic dispatch (virtual)).
These function is predefined by my Engine, where the parameter must
but the parent function "Actor". So if any Actor collides with the
Mesh, the function is called. In this case for me i see no other
solution, than getting the instance of the Actor object to know if its
a player of just something else
A simple virtual function in the Actor base class can be a noop. Override it in Unit class, and specialize it even more in Hero and Player if needed. Non-Unit Actor's will call an empty method. Cleaner than RTTI and the instanceof idiom.
It is ok to have a default base implementation that expects to be overridden by specialized descendants. That is the point of abstract base classes, except in this case you are providing a default implementation that does nothing. The idea is that you are dispatching the "DoCollision" message (a virtual function in C++). You don't care which classes handle it or how. Just that the object has the DoCollision compile-time "interface" and that you dispatched it correctly.

Why bother with virtual functions in c++?

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.

If a class might be inherited, should every function be virtual?

In C++, a coder doesn't know whether other coders will inherit his class. Should he make every function in that class virtual? Are there any drawbacks? Or is it just not acceptable at all?
In C++, you should only make a class inheritable from if you intend for it to be used polymorphically. The way that you treat polymorphic objects in C++ is very different from how you treat other objects. You don't tend to put polymorphic classes on the stack, or pass them by or return them from functions by value, since this can lead to slicing. Polymorphic objects tend to be heap-allocated, be passed around and returns by pointer or by reference, etc.
If you design a class to not be inherited from and then inherit from it, you cause all sorts of problems. If the destructor isn't marked virtual, you can't delete the object through a base class pointer without causing undefined behavior. Without the member functions marked virtual, they can't be overridden in a derived class.
As a general rule in C++, when you design the class, determine whether you want it be inherited from. If you do, mark the appropriate functions virtual and give it a virtual destructor. You might also disable the copy assignment operator to avoid slicing. Similarly, if you want the class not to be inheritable, don't give it any of these functions. In most cases it's a logic error to inherit from a class that wasn't designed to be inherited from, and most of the times you'd want to do this you can often use composition instead of inheritance to achieve this effect.
No, not usually.
A non-virtual function enforces class-invariant behavior. A virtual function doesn't. As such, the person writing the base class should think about whether the behavior of a particular function is/should be class invariant or not.
While it's possible for a design to allow all behaviors to vary in derived classes, it's fairly unusual. It's usually a pretty good clue that the person who wrote the class either didn't think much about its design, lacked the resolve to make a decision.
In C++ you design your class to be used either as a value type or a polymorphic type. See, for example, C++ FAQ.
If you are making a class to be used by other people, you should put a lot of thought into your interface and try to work out how your class will be used. Then make the decisions like which functions should be virtual.
Or better yet write a test case for your class, using it how you expect it to be used, and then make the interface work for that. You might be surprised what you find out doing it. Things you thought were absolutely necessary might turn out to be rarely needed and things that you thought were not going to be used might turn out to be the most useful methods. Doing it this way around will save you time not doing unnecessary work in the long run and end up with solid designs.
Jerry Coffin and Dominic McDonnell have already covered the most important points.
I'll just add an observation, that in the time of MFC (middle 1990s) I was very annoyed with the lack of ways hook into things. For example, the documentation suggested copying MFC's source code for printing and modifying, instead of overriding behavior. Because nothing was virtual there.
There are of course a zillion+1 ways to provide "hooks", but virtual methods are one easy way. They're needed in badly designed classes, so that the client code can fix things, but in those badly designed classes the methods are not virtual. For classes with better design there is not so much need to override behavior, and so for those classes making methods virtual by default (and non-virtual only as active choice) can be counter-productive; as Jerry remarked, virtuals provide opportunites for derived classes to screw up.
There are design patterns that can be employed to minimize the possibilities of screw-ups.
For example, wrapping internal virtuals in exposed non-virtual methods with sanity checks, and, for example, using decoupled event handling (where appropriate) instead of virtuals.
Cheers & hth.,
When you create a class, and you want that class to be used polymorphically you have to consider that the class has two different interfaces. The user interface is defined by the set of public functions that are available in your base class, and that should pretty much cover all operations that users want to perform on objects of your class. This interface is defined by the access qualifiers, and in particular the public qualifier.
There is a second interface, that defines how your class is to be extended. At that level you have to think on what behavior you want to be overridden by extending classes, and what elements of your object you want to provide to extending classes. You offer access to derived classes by means of the protected qualifier, and you offer extension points by means of virtual functions.
You should try to follow the Non-Virtual Interface idiom whenever possible. That idiom (google for it) basically tries to fully separate the two interfaces by not having public virtual functions. Users call non-virtual functions, and those in turn call on configurable functionalities by means of protected/private virtual functions. This clearly separates extension points from the class interface.
There is a single case, where virtual has to be part of the user interface: the destructor. If you want to offer your users the ability to destroy derived objects through pointers to the base, then you have to provide a virtual destructor. Else you just provide a protected non-virtual one.
He should code the functions as it is, he shouldn't make them virtual at all, as in the circumstances specified by you.
The reasons being
1> The CLASS CODER would obviously have certain use of functions he is using.
2> The inherited class may or may not make use of these functions as per requirement.
3> Any function may be overwritten in derived class without any errors.

Using non-abstract class as base

I need to finish others developer work but problem is that he started in different way...
So now I found in situation to use existing code where he chooses to inherit a non-abstract class (very big class, without any virtual functions) that already implements bunch of interfaces or to dismiss that code (which shouldn't be to much work) and to write another class that implements interfaces I need.
What are the pros and cons that would help me to choose the better approach.
p.s. please note that I don't have to much experience
Many Thanks
Although it is very tempting to say write it from scratch again, don't do it! The existing code may be ugly, but it looks like it does work. Since the class is big, I assume there is fair bit of history behind it as well. It might have solutions for some very obscure cases which you might not have imagined till now. What I suggest is, if possible first talk to the person who developed that class, understand how it works, then derive from it (after making its destructor virtual of course) and complete your work. Then as and when time permits slowly refactor the parts of the class into smaller more manageable classes. Also, don't forget to write a good unit-tester before you start so that you can validate the new behavior against the existing class's behavior. One more thing, there is nothing wrong in inheriting from a non-abstract base class as long as it makes sense and the base class destructor is virtual.
If the other developer has written a base-class with no virtual functions, then those functions do not need to be overridden, and it is correct to define them in a non-abstract base class.
If those functions define functionality that all the child-classes require then it would be a mistake to get rid of the base class, as you would then need to implement those functions individually in each of the child classes.
I've seen a lot of developers go 'interface-mad' in the last couple of years, but base classes still serve a function over interfaces - to provide a concrete implementation that is common to all child classes. It would be a mistake to get rid of the base class and have seperate implementations of these functions in each of the child classes.
HOWEVER, if the child classes are inheriting functionality that they do not require, or require a separate implementation of, then the Base class is a mistake and interfaces would seem like the better option to divide the functionality between the child classes.
Despite this, I would agree with Naveen that its probably not worth the extra work this will give you, it may seem simple, but if this is a big class with a lot of inheritors then it could turn out to be a nightmare. Quite often in Software Engineering you have to deal with another developer's code that you might have implemented differently. If you re-implemented it ever time you will be a very unproductive developer. I say work with what you've got and get the project finished on time.
Is there anything at all you want to use from the base class or would you end up overriding everything?
Does it define some sort of type that you want to use for an "is-a" relationship?
(for example, base class is "animal" and you want to make "cat", but if it doesn't add any behavior to its interface, that doesn't seem likely)
Is the base class used in other interfaces you need to use? (like if someone is passing objects through a reference/pointer to the base class)
If not, I'd say there's no advantage in inheriting from that class over implementing the interface(s) yourself.
What are the pros and cons that would help me to choose the better approach.
It's legal to derive from a class with no virtual functions, but that doesn't make it a good idea. When you derive from a class with virtual functions, you often use that class through pointers (eg., a class Derived that inherits from Base is often manipulated through Base*s). That doesn't work when you don't use virtual functions. Also, if you have a pointer to the base class, delete-ing it can lead to a memory leak.
However, it sounds more like these classes aren't being used through pointers-to-the-base. Instead the base class is simply used to get a lot of built in functionality, although the classes aren't related in the normal sense. Inversion of control (and has-a relationships) is a more common way to do that nowadays (split the functionality of the base class into a number of interfaces -- pure virtual base classes -- and then have the objects that currently derive from the base class instead have member variables of those interfaces).
At the very least, you'll want to split the big base class into well-defined smaller classes and use those (like mixins), which sounds like your second option.
However, that doesn't mean rewrite all the other code that uses the blob base class all in one go. That's a big undertaking and you're likely to make small typos and similar mistakes. Instead, buy yourself copies of Working Effectively With Legacy Code and Large-Scale C++ Software Design, and do the work piecemeal.
From you question it is not too clear what the problem is - looking at the title (Using non-abstract class as base) I can tell you that using an abstract class (non pure virtual - when you talk about interfaces in C++ I am assuming pure virtual abstract classes) as base makes sense only if there is common functionality you can share between subclasses - meaning that a number of classes extend the same abstract class inheriting the common implementation. If that's not the case (and you're pretty confident it's never gonna happen) then it doesn't make sense to use an abstract class.
If you can extract out some of the functionality in you big class in such a way that leads to (even potential) code reuse then it could make sense - otherwise I wouldn't see the point.

C++ : implications of making a method virtual

Should be a newbie question...
I have existing code in an existing class, A, that I want to extend in order to override an existing method, A::f().
So now I want to create class B to override f(), since I don't want to just change A::f() because other code depends on it.
To do this, I need to change A::f() to a virtual method, I believe.
My question is besides allowing a method to be dynamically invoked (to use B's implementation and not A's) are there any other implications to making a method virtual? Am I breaking some kind of good programming practice? Will this affect any other code trying to use A::f()?
Please let me know.
Thanks,
jbu
edit: my question was more along the lines of is there anything wrong with making someone else's method virtual? even though you're not changing someone else's implementation, you're still having to go into someone's existing code and make changes to the declaration.
If you make the function virtual inside of the base class, anything that derives from it will also have it virtual.
Once virtual, if you create an instance of A, then it will still call A::f.
If you create an instance of B and store it in a pointer of type A*. And then you call A*::->f, then it will call B's B::f.
As for side effects, there probably won't be any side effects, other than a slight (unnoticeable) performance loss.
There is a very small side effect as well, there could be a class C that also derives from A, and it may implement C::f, and expect that if A*::->f was called, then it expects A::f to be called. But this is not very common.
But more than likely, if C exists, then it does not implement C::f at all, and in which case everything is fine.
Be careful though, if you are using an already compiled library and you are modifying it's header files, what you are expecting to work probably will not. You will need to recompile the header and source files.
You could consider doing the following to avoid side effects:
Create a type A2 that derives from A and make it's f virtual
Use pointers of type A2 instead of A
Derive B from type A2.
In this way anything that used A will work in the same way guaranteed
Depending on what you need you may also be able to use a has-a relationship instead of a is-a.
There is a small implied performance penalty of a vtable lookup every time a virtual function is called. If it were not virtual, function calls are direct, since the code location is known at compile time. Wheras at runtime, a virtual function address must be referenced from the vtable of the object you're calling upon.
To do this, I need to change A::f() to
a virtual method, I believe.
Nope, you do not need to change it to a virtual method in order to override it. However, if you are using polymorphism you need to, i.e. if you have a lot of different classes deriving from A but stored as pointers to A.
There's also a memory overhead for virtual functions because of the vtable (apart from what spoulson mentioned)
There are other ways of accomplishing your goal. Does it make sense for B to be an A? For example, it makes sense for a Cat to be an Animal, but not for a Cat to be a Dog. Perhaps both A and B should derive from a base class, if they are related.
Is there just common functionality you can factor out? It sounds to me like you'll never be using these classes polymorphically, and just want the functionality. I would suggest you take that common functionality out and then make your two separate classes.
As for cost, if you're using A ad B directly, the compile will by-pass any virtual dispatching and just go straight to the functions calls, as if they were never virtual. If you pass a B into a place expecting `A1 (as a reference or pointer), then it will have to dispatch.
There are 2 performance hits when speaking about virtual methods.
vtable dispatching, its nothing to really worry about
virtual functions are never inlined, this can be much worse than the previous one, function inlining is something that can really speed things in some situations, it can never happen with a virtual function.
How kosher it is to change somebody else's code depends entirely on the local mores and customs. It isn't something we can answer for you.
The next question is whether the class was designed to be inherited from. In many cases, classes are not, and changing them to be useful base classes, without changing other aspects, can be tricky. A non-base class is likely to have everything private except the public functions, so if you need to access more of the internals in B you'll have to make more modifications to A.
If you're going to use class B instead of class A, then you can just override the function without making it virtual. If you're going to create objects of class B and refer to them as pointers to A, then you do need to make f() virtual. You also should make the destructor virtual.
It is good programming practise to use virtual methods where they are deserved. Virtual methods have many implications as to how sensible your C++ Class is.
Without virtual functions you cannot create interfaces in C++. A interface is a class with all undefined virtual functions.
However sometimes using virtual methods is not good. It doesn't always make sense to use a virtual methods to change the functionality of an object, since it implies sub-classing. Often you can just change the functionality using function objects or function pointers.
As mentioned a virtual function creates a table which a running program will reference to check what function to use.
C++ has many gotchas which is why one needs to be very aware of what they want to do and what the best way of doing it is. There aren't as many ways of doing something as it seems when compared to runtime dynamic OO programming languages such as Java or C#. Some ways will be either outright wrong, or will eventually lead to undefined behavior as your code evolves.
Since you have asked a very good question :D, I suggest you buy Scott Myer's Book: Effective C++, and Bjarne Stroustrup's book: The C++ Programming Language. These will teach you the subtleties of OO in C++ particularly when to use what feature.
If thats the first virtual method the class is going to have, you're making it no longer a POD. This can break things, although the chances for that are slim.
POD: http://en.wikipedia.org/wiki/Plain_old_data_structures