Inheritance, hiding functions, and scopes c++ - c++

Say I have an inherited class with function A and B. B does something and call A.
Base class also have function A and B. B does the thing in a different way and then call A (the derived class's A). However in a specific situation I want to call the base class's B. This is done using Base::B(). Then B will call A, my question is, which A will it call? The base one or the inherited one?

It depends whether A is virtual or not. If virtual the derived version will be called, if not it will be the base version.

You are proposing a generic scenario here, but it's enough to determine that you are referring to the MRO, aka Method Resolution Order, which is the algorithm ( or the class of algorithms, you can use this acronym to refer to a general topic or a specific single thing ) used to determine which method needs to be called.
How the MRO works in the C++ case it's described in the standard itself, but there is a dedicated tag here on SO named method-resolution-order and an answer that can give you a broad view about this.

Related

Virtual functions versus Callbacks

Consider a scenario where there are two classes i.e. Base and Derived. If the Base class wants to call a function of the derived class, it can do so by either making a virtual function and defining that VF in the derived class or by using callbacks. I want to know in what should be preferred out of the two? Choosing among the two depends on which situations/conditions?
EDIT:
Question Clarification:
The situation I was referring to is that there is a base class which receives messages. These different messages are to be handled differently by the derived class, so one way is to create a virtual function and let the derived class implement it, handling every message though various switch cases.
Another way is to implement the callbacks through the function pointers (pointing to the functions of derived class) inside the templates (templates are needed for handling the object of the derived class and the function names). The templates and the function pointers are going to reside in the base class.
A virtual function call is actually a callback.
The caller looks up the corresponding entry in the object's virtual function table and calls it. That's exactly like a callback behaves, except that member function pointers have awkward syntax. Virtual functions offload the work to the compiler, which makes them a very elegant solution.
Virtual functions are the way to communicate within the inheritance hierarchy.
I think this comes down to a decision about whether or not the behaviour you're talking about is something that belongs in the heirarchy that 'Base' knows about and child implements.
If you go with a callback solution, then the callback method (depending on signature) doesn't have to be implemented in a child of Base. This may be appropriate if for example you wanted to say 'this event has happened' to an 'event listener' that could be in a derived class, or could be in a totally unrelated class that happens to be interested in the event.
If you go with the virtual function solution, then you're more tightly coupling the implentation of the Derived and Base classes.
An interesting read, which may go some way to answering your question is: Callbacks in C++ which talks about the usage of Functors. There's also an example on Wikipedia that uses a template callback for sorting. You'll notice that the implementation for the callback (which is a comparison function) does not have to be in the object that is performing the sort. If it were implemented using virtual methods, this wouldn't be the case.
I don't think that the two cases you are describing are comparable. Virtual functions are a polymorphism tool that aid you in extending a base class in order to provide additional functionality. The key characteristic of them is that the decision which function will be called is made in runtime.
Callbacks are a more general concept, that doesn't apply only on a Parent-Child class relationship.
So, if you want to do involves extending a base class, I would certainly go with virtual functions. Be sure however to understand how virtual functions work.

Virtual dispatch implementation details

First of all, I want to make myself clear that I do understand that there is no notion of vtables and vptrs in the C++ standard. However I think that virtually all implementations implement the virtual dispatch mechanism in pretty much the same way (correct me if I am wrong, but this isn't the main question). Also, I believe I know how virtual functions work, that is, I can always tell which function will be called, I just need the implementation details.
Suppose someone asked me the following:
"You have base class B with virtual functions v1, v2, v3 and derived class D:B which overrides functions v1 and v3 and adds a virtual function v4. Explain how virtual dispatch works".
I would answer like this:
For each class with virtual functions(in this case B and D) we have a separate array of pointers-to-functions called vtable.
The vtable for B would contain
&B::v1
&B::v2
&B::v3
The vtable for D would contain
&D::v1
&B::v2
&D::v3
&D::v4
Now the class B contains a member pointer vptr. D naturally inherits it and therefore contains it too. In the constructor and destructor of B B sets vptr to point to B's vtable. In the constructor and destructor of D D sets it to point to D's vtable.
Any call to a virtual function f on an object x of polymorphic class X is interpreted as a call to x.vptr[f's position in vtables]
The questions are:
1. Do I have any errors in the above description?
2. How does the compiler know f's position in vtable (in detail, please)
3. Does this mean that if a class has two bases then it has two vptrs? What is happening in this case? (try to describe in a similar manner as I did, in as much detail as possible)
4. What's happening in a diamond hierarchy with A on top B,C in the middle and D at the bottom? (A is a virtual base class of B and C)
Thanks in advance.
1. Do I have any errors in the above description?
All good. :-)
2. How does the compiler know f's position in vtable
Each vendor will have their own way of doing this, but I always think of the vtable as map of the member function signature to memory offset. So the compiler just maintains this list.
3. Does this mean that if a class has two bases then it has two vptrs? What is happening in this case?
Typically, compilers compose a new vtable which consists of all the vtables of the virtual bases appended together in the order they were specified, along with the vtable pointer of the virtual base. They follow this with the vtable functions of the deriving class. This is extremely vendor-specific, but for class D : B1, B2, you typically see D._vptr[0] == B1._vptr.
That image is actually for composing the member fields of an object, but vtables can be composed by the compiler in the exact same way (as far as I understand it).
4. What's happening in a diamond hierarchy with A on top B,C in the middle and D at the bottom? (A is a virtual base class of B and C)
The short answer? Absolute hell. Did you virtually inherit both the bases? Just one of them? Neither of them? Ultimately, the same techniques of composing a vtable for the class are used, but how this is done varies way to wildly, since how it should be done is not at all set in stone. There is a decent explanation of solving the diamond-hierarchy problem here, but, like most of this, it is quite vendor-specific.
Looks good to me
Implementation specific, but most are just in source code order -- meaning the order they appear in the class -- starting with the base class, then adding on new virtual functions from the derived. As long as the compiler has a deterministic way of doing this, then anything it wants to do is fine. However, on Windows, to create COM compatible V-Tables, it has to be in source order
(not sure)
(guess) A diamond just means that you could have two copies of a base class B. Virtual inheritance will merge them into one instance. So if you set a member via D1, you can read it via D2. (with C derived from D1, D2, each of them derived from B). I believe that in both cases, the vtables would be identical, as the function pointers are the same -- the memory for data members is what is merged.
Comments:
I don't think destructors come into it!
A call such as e.g. D d; d.v1(); will probably not be implemented via the vtable, as the compiler can resolve the function address at compile/link-time.
The compiler knows f's position because it put it there!
Yes, a class with multiple base classes will typically have multiple vptrs (assuming virtual functions in each base class).
Scott Meyers' "Effective C++" books explain multiple inheritance and diamonds better than I can; I'd recommend reading them for this (and many other) reasons. Consider them essential reading!

Inheritance in C++ internals

Can some one explain me how inheritance is implemented in C++ ?
Does the base class gets actually copied to that location or just refers to that location ?
What happens if a function in base class is overridden in derived class ? Does it replace it with the new function or copies it in other location in derived class memory ?
first of all you need to understand that C++ is quite different to e.g. Java, because there is no notion of a "Class" retained at runtime. All OO-features are compiled down to things which could also be achieved by plain C or assembler.
Having said this, what acutally happens is that the compiler generates kind-of a struct, whenever you use your class definition. And when you invoke a "method" on your object, actually the compiler just encodes a call to a function which resides somewhere in the generated executable.
Now, if your class inherits from another class, the compiler somehow includes the fields of the baseclass in the struct he uses for the derived class. E.g. it could place these fields at the front and place the fields corresponding to the derived class after that. Please note: you must not make any assumptions regarding the concrete memory layout the C++ compiler uses. If you do so, you're basically on your own and loose any portability.
How is the inheritance implemented? well, it depends!
if you use a normal function, then the compiler will use the concrete type he's figured out and just encode a jump to the right function.
if you use a virtual function, the compiler will generate a vtable and generate code to look up a function pointer from that vtable, depending on the run time type of the object
This distinction is very important in practice. Note, it is not true that inheritance is allways implemented through a vtable in C++ (this is a common gotcha). Only if you mark a certain member function as virtual (or have done so for the same member function in a baseclass), then you'll get a call which is directed at runtime to the right function. Because of this, a virtual function call is much slower than a non-virtual call (might be several hundered times)
Inheritance in C++ is often accomplished via the vtable. The linked Wikipedia article is a good starting point for your questions. If I went into more detail in this answer, it would essentially be a regurgitation of it.

Is there a way to determine at runtime if an object can do a method in C++?

In Perl, there is a UNIVERSAL::can method you can call on any class or object to determine if it's able to do something:
sub FooBar::foo {}
print "Yup!\n" if FooBar->can('foo'); #prints "Yup!"
Say I have a base class pointer in C++ that can be any of a number of different derived classes, is there an easy way to accomplish something similar to this? I don't want to have to touch anything in the other derived classes, I can only change the area in the base class that calls the function, and the one derived class that supports it.
EDIT: Wait, this is obvious now (nevermind the question), I could just implement it in the base that returns a number representing UNIMPLEMENTED, then check that the return is not this when you call it. I'm not sure why I was thinking of things in such a complicated manner.
I was also thinking I would derive my class from another one that implemented foo then see if a dynamic cast to this class worked or not.
If you have a pointer or reference to a base class, you can use dynamic_cast to see which derived class it is (and therefore which derived class's methods it supports).
If you can add methods to the base class, you can add a virtual bool can_foo() {return false;} and override it in the subclass that has foo to return true.
C++ does not have built in run-time reflection. You are perfectly free to build your own reflection implementation into your class hierarchy. This usually involves a static map that gets populated with a list of names and functions. You have to manually register each function you want available, and have consistency as to the calling convention and function signature.
I believe the most-correct way would be to use the typeid<> operator and get a reference to the type_info object, and then you could compare that (== operator) to the desired type_info for the data types you wish to care about.
This doesn't give you method-level inspection, and does require that you've built with RTTI enabled (I believe that using typeid<> on an object that was built without RTTI results with "undefined" behavior), but there you are.
MSDN has an online reference to get you started : http://msdn.microsoft.com/en-us/library/b2ay8610%28VS.80%29.aspx

Calling overridden function from the overriding function

Suppose I have virtual function foo() in class B, and I need slightly different behavior in one of B's derived classes, class D. Is it OK to create an overriding function D::foo(), and call B::foo() from there, after the special case treatment? Like this:
void D::foo()
{
if (/*something*/)
// do something
else
B::foo();
}
I am not asking whether that would work, I know it will. I want to know, whether it is right in terms of a good OOD.
This is perfectly good. In fact, the canonical way of performing some operations is calling the base class method, then do whatever (or the other way around). I am thinking of operator= here. Constructors usually work that way, too, even if this is a bit disguised in the initialization list.
Yes, its totally ok as long as you are not violating the Liskov Substitution Principle.
Yes, it is.
I have seen GUI frameworks use this to fall back on the base class's default implementation which contained code to signal errors/throw an exception/return a generic value.
It's ok. Syntax you had gave can be also used to temporary turn off polymorphism, i.e. when you call obj->B::foo() method will be chosen from class B regardless if foo() is virtual or not and if obj is instance of B or not (it must be an instance of class extending B though).
Yes it is , that's what your compiler do for you every time it generates a constructor and a destructor: calling the mother's one for instance. I often rely on that"trick" in my own code.
It's fine to call base's implementation, but doing it conditionally moves you apart from constructor semantic, contrary to what have been suggested in other answers.
You may run into fragile base class issue in two ways :
By assuming B::foo() provides common behavior for the whole hierarchy (ie, forgetting the method isn't always called)
Nasty problems depending on what // do something actually does !
For completeness, let's mention a symmetric design approach : Template pattern (base implementation calling specific sub-part)