Consider a simple picture below.
Here Child inherit's its properties from both, Parent 1 and Parent 2, and Also the properties directly from the Grand Parent.
Let each be seperate class.
* Its obvious that, to avoid the conflict of child inheriting the properties of parent 1 and parent 2, we make a base class "virtual" .
From, where ever I've learnt I was instructed that in mainfunction, In child class, I could get the properties of parent or grandparent.
I get confused when, I try to think what happens with
Compiler and Memory side internally.
Let display() be the member function of all Grandparent and parent1 and parent2. Now the virtual base class takes necessary steps, to avoid ambiguity in the child which actually has two duplicate sets of parent1 and parent2, yes also the grandparent.
Now, I want to make myself clear that
If the display() of the grandparent is accessed from the child using pointer and addresses internally. child won't be having the any duplicate sets. So, there won't araise any ambiguity therefore why else are we going for virtual funtions?
In other case, What I'm thinking above is wrong, and consider that display() of grandparent is actually or I assume to be copied into the child,and the same should happen with the parent1 and parent2. (Please, don't say that base child will be having access or containing public and protected members of grandparent, parent1 and parent2 , I'm sorry, the reason is that, this is the answer I found on Internet and it doesn't clarify me, when I think how I happens) As a result, child should be having same member function in the same class of child, this should definitely give problems because child couldn't have same member functions as even constructors differ in arguments.
Any other cases are possible, please explain.
I made my maximum effort to detail my doubt.
If possible, help me to understand how exactly the virtual classes and inheritance concepts work.
Thank you.
--
A derived class is composed of everything that the base class is PLUS your extra bits. No copying takes place because a class is just like a design. It's the object where stuff actually exists. When you instantiate the derived class (create an object of it) it will contain members of the derived and base class as one.
Your class is like a blueprint - the design for a house. I could design a house with 1 bedroom, 1 bathroom and a kitchen. This blueprint is like your class. I can't pee in the bathroom yet: it's just a design on paper. I can't make a sandwich in kitchen. Now I can choose to have the house built - this is then an object. Now I can take a pee. It's quite a relief, I had to wait ages. In fact I can make as many copies of this house as I like. Making copies is instantiating more objects.
But one day I think to myself I'd like a bigger house based on this one so I make a new design that I can simply add to the old design extending the house. This is inheritance. My new design has a lounge added on and another toilet (I need to pee a lot, ok?). When I instantiate this version of my design I'll get a house which contains a bedroom from the 1st design, and bathroom, and kitchen as well as my lounge.
Sounds to me like you need to get a good book on object oriented programming. It won't be as amazing as my explanation there, no doubt, and probably won't talk about toilets as much as one would normally like, however it will explain much more than this. Good luck.
An object of a derived type contains within it a subobject of the base type. When you call a non-virtual, non-static member function of the base class, then that function is effectively invoked on that base subobject.
(Note that it is possible to have multiple base subobjects of the same type when you use multiple inheritance.)
Virtual functions behave somewhat differently: a virtual call always requests a (usually dynamic) search for the most-derived object of which the invoked object is a base subobject, and then call the last overrider of the function. But that's essentially unrelated to the point of the question. For example, when you have struct A { virtual void f(); }; struct B : A {}; and then call B().f(), that call is still performed on the A-subobject – the virtual dispatch only starts there.
Related
Suppose in C++, if we have a base class Base and a child class derived:
class Base{
protected:
int x_base;
};
class Derived : public Base {
public:
int x_prot;
};
Than in the main we can create a pointer to the base class and let it point to a derived class object:
Base *b;
b=new Derived;
But this instead is not allowed:
Derived *b;
b=new Base;
I would have thought the opposite.
When we call Base* b we are saying to the code that b will be a pointer to an object to class Base. In the example, he will be ready to allocate space for x_base (but not for x_prot). So we should not be able to use the pointer of the base class to point to an object of the child class.
Where is the error in my reasoning?
When we call Base* b we are saying to the code that b will be a pointer to an object to class Base.
We are indeed saying that. And it is true! Every Derived object starts with a Base sub-object. That's the nature of inheritance. A Derived is a Base plus some additional stuff on the end.
It's perfectly fine to make a pointer that completely ignores the additional stuff on the end: that is what an upcast does.
In the example, he will be ready to allocate space for x_base (but not for x_prot)
Pointers don't allocate things. They point to things.
In fact, your reasoning is exactly why Derived* b=new Base; is broken - the thing that does create an object (i.e. new) is only creating a Base, not a Derived. To then say that b points to a thing that can be treated as a full Derived would simply be untrue. You're missing all the additional stuff on the end.
Where is the error in my reasoning?
I think that you are thinking of the pointers as the things that create the objects, but that is not true. They are things that point to objects that were created by something else (e.g. new).
Let's say you invited a plumber to your home for the next Tuesday. And only thing you know he is a base plumber. You also know that there are 2 types of plumbers - base one and extended. Base plumber can repair a pipe. Extended one can do what base one does and also can install a water heater as well. You do not know which one will come to your house base one or extended, so it is safe to assume he is base. So when guy arrives you can ask him to repair your pipe and you will be fine. But let's say you want your heater installed as well. You cannot ask this guy to install it as he came just as base plumber. So you have 2 options:
You tell the guy - I do not care who you are or I've seen you doing your job somewhere else or some other way I realized so I assume you are an extended plumber. So I call you now extended and go install my heater. So if your assumption is right you will be fine. If you are wrong then guy may install water heater upside down, can brake it completely or even make your whole house to explode.
You ask the guy: are you an extended plumber? If he says yes, then you tell him - install the heater. So you either would be fine or would not have the work done.
So back to your case - it is safe to treat extended plumber as base one, they both can repair a pipe. On another side it is not safe to assume that a plumber is extended so you either need a way to know that or ask him. First one is done by static_cast<> and the second by dynamic_cast<>. But it should be more clear now why converting derived class pointer (extended plumber) to base is safe but not the vice versa.
I have two containers (call them type A and type B), both derived from a parent type (call it AB). The parent class has a linked list of Widget objects. In my Widget class, I have a pointer back to the container it's in. Obviously this is declared as a pointer to AB. Also in the widget class, I have a method that ONLY applies if the widget's container is A, and it uses the pointer to AB. But of course, I would need to cast it to an A* .
I've considered making the method a virtual method in AB, and have it throw an error; and then overriding it in A, but this bothers me because the method only applies to A and doesn't make sense in the generic AB case.
I've considered using dynamic_cast to cast the parent pointer to A*. But I've also read that this suggests poor class design. What's the preferred way to handle this?
class Widget;
class AB
{
private:
Widget* firstWidget; // first widget in a linked list, don't judge.
};
class A : public AB
{
public:
void methodSpecificToA() {}
};
class B : public AB {};
class Widget
{
private:
AB* container;
public:
void AWidgetMethod()
{
A* ac = static_cast<A*>(container);
ac->methodSpecificToA();
}
};
The comments mentioned a desire to not have the base class provide all virtual methods that some derived class might need. This desire is a Good Thing. Let's see if I can lay out some alternatives. (I make no claims about this being exhaustive.) Please recognize that these are generic, as the question involves few specifics about the context. So I'm guessing a bit. I don't know what is best for the given scenario.
Before looking at alternatives, what is wrong with the design? The main problem is that the Widget class knows something about the AB hierarchy, then it makes decisions based upon this knowledge. The less your classes know about each other, the more isolated they are. For people, isolation is bad, but for classes it means less interdependence and fewer bugs introduced when one of the classes changes. Ideally, the Widget class knows the generic AB interface and nothing else in the hierarchy. Maybe a class derived from Widget knows something about a class derived from AB. Or maybe not. There are different approaches that can be taken.
Say what happened, not what to do. One reason this situation might come up is that the widget responds to a certain stimulus by telling the container to do something. Sometimes one should take a look at all the things a container might need to do, and compare that to all the things a container might need to respond to. You might end up with a shorter list of virtual functions if there is one per stimulus rather than one per action taken. Plus, a function for a stimulus should feel applicable to the base class, whereas a function for an action might not. (For example, a function for a stimulus might be WasPressed(Widget & widget).) If you go with this approach, the widget responds to a certain stimulus by telling the container that the stimulus occurred, letting the container decide what it needs to do. In some cases, this by itself reduces the knowledge one class has about another. In other cases, it will seem more contrived (in which case, it's not necessarily a good idea).
Specialized classes deserve specialized data. Well, not always. Still, there are times when it's worth a little extra bookkeeping to keep your code robust in the face of maintenance (a.k.a. other people "improving" your code). I am thinking of the situation where the widget calling methodSpecificToA knows its container is an A because it is a certain type of widget. For example, a scrollbar would know that its parent is a scrollable area because that's the only kind of container that would want a scrollbar. In this case, it may be worth having the specialized widget maintain its own pointer to its container, stored as a pointer to A. (This is in addition to the pointer to AB that you already have.) No casting is necessary, and it may even be possible to separate this special functionality from the concept "my container". (Maybe A should have two base classes: AB and one that defines methodSpecificToA. If you do this, the specialized widget would store a pointer to this new base class.)
Use a callback. This classic method works wonders when it comes to one class not needing to know anything about another class. It works even if the widget is not specialized, but works best if there are not many callbacks needed. (If many callbacks are needed, "specialized data" as above might be better.) With a callback, the widget is told to call a certain function object when a certain stimulus happens, so that's what it does. No knowledge of what's going to happen, and no need for a pointer to its container. The knowledge of how containers and widgets interact shifts from the widget to the code that places widgets in containers. (This is the code that would set up the callback.)
One thing you might notice about these suggestions is that none of them tells you how to call methodSpecificToA from a pointer to AB. That is why I suggest looking deeper into this sort of issue. Once you see a warning flag that you may have a design flaw, it's often a good idea to review your design. The whole design, not just the small part where the flag appeared.
Can someone explains how this virtual table for the different class is stored in memory? When we call a function using pointer how do they make a call to function using address location? Can we get these virtual table memory allocation size using a class pointer? I want to see how many memory blocks is used by a virtual table for a class. How can I see it?
class Base
{
public:
FunctionPointer *__vptr;
virtual void function1() {};
virtual void function2() {};
};
class D1: public Base
{
public:
virtual void function1() {};
};
class D2: public Base
{
public:
virtual void function2() {};
};
int main()
{
D1 d1;
Base *dPtr = &d1;
dPtr->function1();
}
Thanks! in advance
The first point to keep in mind is a disclaimer: none of this is actually guaranteed by the standard. The standard says what the code needs to look like and how it should work, but doesn't actually specify exactly how the compiler needs to make that happen.
That said, essentially all C++ compilers work quite similarly in this respect.
So, let's start with non-virtual functions. They come in two classes: static and non-static.
The simpler of the two are static member functions. A static member function is almost like a global function that's a friend of the class, except that it also needs the class`s name as a prefix to the function name.
Non-static member functions are a little more complex. They're still normal functions that are called directly--but they're passed a hidden pointer to the instance of the object on which they were called. Inside the function, you can use the keyword this to refer to that instance data. So, when you call something like a.func(b);, the code that's generated is pretty similar to code you'd get for func(a, b);
Now let's consider virtual functions. Here's where we get into vtables and vtable pointers. We have enough indirection going on that it's probably best to draw some diagrams to see how it's all laid out. Here's pretty much the simplest case: one instance of one class with two virtual functions:
So, the object contains its data and a pointer to the vtable. The vtable contains a pointer to each virtual function defined by that class. It may not be immediately apparent, however, why we need so much indirection. To understand that, let's look at the next (ever so slightly) more complex case: two instances of that class:
Note how each instance of the class has its own data, but they both share the same vtable and the same code--and if we had more instances, they'd still all share the one vtable among all the instances of the same class.
Now, let's consider derivation/inheritance. As an example, let's rename our existing class to "Base", and add a derived class. Since I'm feeling imaginative, I'll name it "Derived". As above, the base class defines two virtual functions. The derived class overrides one (but not the other) of those:
Of course, we can combine the two, having multiple instances of each of the base and/or derived class:
Now let's delve into that in a little more detail. The interesting thing about derivation is that we can pass a pointer/reference to an object of the derived class to a function written to receive a pointer/reference to the base class, and it still works--but if you invoke a virtual function, you get the version for the actual class, not the base class. So, how does that work? How can we treat an instance of the derived class as if it were an instance of the base class, and still have it work? To do it, each derived object has a "base class subobject". For example, lets consider code like this:
struct simple_base {
int a;
};
struct simple_derived : public simple_base {
int b;
};
In this case, when you create an instance of simple_derived, you get an object containing two ints: a and b. The a (base class part) is at the beginning of the object in memory, and the b (derived class part) follows that. So, if you pass the address of the object to a function expecting an instance of the base class, it uses on the part(s) that exist in the base class, which the compiler places at the same offsets in the object as they'd be in an object of the base class, so the function can manipulate them without even knowing that it's dealing with an object of the derived class. Likewise, if you invoke a virtual function all it needs to know is the location of the vtable pointer. As far as it cares, something like Base::func1 basically just means it follows the vtable pointer, then uses a pointer to a function at some specified offset from there (e.g., the fourth function pointer).
At least for now, I'm going to ignore multiple inheritance. It adds quite a bit of complexity to the picture (especially when virtual inheritance gets involved) and you haven't mentioned it at all, so I doubt you really care.
As to accessing any of this, or using in any way other than simply calling virtual functions: you may be able to come up with something for a specific compiler--but don't expect it to be portable at all. Although things like debuggers often need to look at such stuff, the code involved tends to be quite fragile and compiler-specific.
The virtual table is supposed to be shared between instances of a class. More precisely, it lives at the "class" level, rather than the instance level. Each instance has the overhead of actually having a pointer to the virtual table, if in it's hierarchy there are virtual functions and classes.
The table itself is at least the size necessary to hold a pointer for each virtual function. Other than that, it is an implementation detail how it's actually defined. Check here for a SO question with more details about this.
First of all, the following answer contain almost everything you want to know regarding virtual tables:
https://stackoverflow.com/a/16097013/8908931
If you are looking for something a little more specific (with the regular disclaimer that this might change between platforms, compilers, and CPU architectures):
When needed, a virtual table is being created for a class. The class will have only one instance of the virtual table, and each object of the class will have a pointer which will point to the memory location of this virtual table. The virtual table itself can be thought of as a simple array of pointers.
When you assigned the derived pointer to the base pointer, it also contain the pointer to the virtual table. This mean that the base pointer points to the virtual table of the derived class. The compiler will direct this call to an offset into the virtual table, which will contain the actual address of the function from the derived class.
Not really. Usually at the start of an object, there is a pointer to the virtual table itself. But this will not help you too much, as it is just an array of pointers, with no real indication of its size.
Making a very long answer short: For an exact size you can find this information in the executable (or in segments loaded from it to the memory). With enough knowledge of how the virtual table works, you can get a pretty accurate estimation, given you know the code, the compiler, and the target architecture.
For the exact size, you can find this information in either the executable, or in segments in the memory which are being loaded from the executable. An executable is usually an ELF file, this kind of files, contain information which is needed to run a program. A part of this information is symbols for various kinds of language constructs such as variables, functions and virtual tables. For each symbol, it contains the size it takes in memory. So button line, you will need the symbol name of the virtual table, and enough knowledge in ELF in order to extract what you want.
The answer that Jerry Coffin gave is excellent in explaining how virtual function pointers work to achieve runtime polymorphism in C++. However, I believe that it is lacking in answering where in memory the vtable is stored. As others have pointed out this is not dictated by the standard.
However, there is an excellent blog post(s) by Martin Kysel that goes into great detail about where virtual tables are stored. To summarize the blog post(s):
One vtable is created for every class (not instance) with virtual functions. Each instance of this class points to the same vtable in memory
Each vtable is stored in read only memory of the resulting binary file
The disassembly for each function in the vtable is stored in the text section of the resulting ELF binary
Attempting to write over the vtable, located in read only memory, results in a Segmentation fault (as expected)
Each class has a pointer to a list of functions, they are each in the same order for derived classes, then the specific functions that are overrided change at that position in the list.
When you point with a base pointer type, the pointed to object still has the correct _vptr.
Base's
Base::function1()
Base::function2()
D1's
D1::function1()
Base::function2()
D2's
Base::function1()
D2::function2()
Further derived drom D1 or D2 will just add their new virtual functions in the list below the 2 current.
When calling a virtual function we just call the corresponding index, function1 will be index 0
So your call
dPtr->function1();
is actually
dPtr->_vptr[0]();
I would like to make sure no one is able to delete any objects from my class hierarchy other then by using a provided Destroy method.
The rationale is that any object from this hierarchy needs to take a special write mutex before it starts to destroy itself to make sure objects are not deleted while another thread is using them.
I know I could prevent this problem with reference counting but it would be a much bigger change to the system also in terms of potential performance impact and memory allocation.
Is there a way to somehow efficiently/smartly make all the destructors protected so that child classes can call their parents destructors while outsiders have to use Destroy?
One solution that is safe (ie. it will not rot) that I came up with is to make all the destructors private and declare each derived class as a friend of the base class but I'd prefer something more elegant, less manual and easier to maintain (like not requiring to modify base classes in order to derive from them).
Is there anything like this available? Maybe some smart trick that makes things "work" as I'd like?
ps. The solution I chose for now is to NOT prevent anyone from calling delete in all cases (just made it protected in the base class) but detect this situation and call abort in the base class destructor.
Don't try to reinvent the lifetime mechanisms provided by the language.
For an object of your class to be correctly initialised it needs to also be able to clean itself up.
In its constructor pass either the mutex, or a means of obtaining a mutex, which it can use in its destructor.
Thanks for all your feedback and discussion. Yes - it proved it's impossible to do what would be my natural first choice :( (to have the "protection" of the destructor take effect in derived classes just as it's "virtuality" does).
My solution in this particular case (solving all potential problems with being able to make hones mistakes by introducing new derived classes that violate previous agreements AND keeping the solution in one place/maintainable (no code duplication in derived classes etc)) is:
Make all the existing class hierarchy destructors I can find protected
Provide a Destroy method in the base class that can be used to initiate the destruction of these objects - if called the method lights up a flag on the destructed object that it was properly destroyed and then calls delete on it
In the base class destructor (once we get to it) check the flag - if it's not set it means someone introduced a new class and called delete on it directly or avoided the compilers protection checks in some other way (abused some friendships etc) - I abort the application in this case to make sure the issue cannot be ignored/missed
I had the same needs, but for a different reason. In our company framework, nearly all classes derive from a common BaseObject class. This object uses a reference count to determine its life time. BaseObject has in particular these three methods: retain(), release() and autorelease(), heavily inspired from Objective-C language. The operator delete is only called inside release() when the retain count reaches 0. Nobody is supposed to call delete directly, and it is also undesirable to have BaseObject instances on stack.
Therefore, all our destructors should be protected or private. To enforce this, as I know it is impossible from the language, I wrote a Perl script that looks for all destructors within a source directory and makes a report. It is then relatively easy to check that the rule is respected.
I made the script public, available here: https://gist.github.com/prapin/308a7f333d6836780fd5
It can be done with help of testing. For a class with an protected destructor you need 2 test cases:
one function (in one file) which fails to compile simply creating such an object
one function (in second file) which creates an object with an derived class which compiles.
If both test cases work I think you can be sure your classes are protected as you like.
I don't know wether you are able to implement it with your build system but I have an example using bjam (from boost) at git hub. The code is simple and works for gcc and msvc. If you don't know bjam you should look inte Jamroot.jam. I think it is clear without any further comment how this simple example works.
If Base is a base class and Derived a derived class and there are 25 instances of Derived, how are the vtables set up to be accessed by all the instances? Where are they loaded in the memory?
Compilers are allowed to implement dynamic dispatch however they want in c++, i don't think there is actually any requirement to even use a vtable at all, but it would be very unusual to find a compiler that didn't.
In most cases i think that each class (that contains some virtual methods) will own a single vtable (so if i had 5 instances of class A i will still only have 1 vtable), but this behaviour should not be relied upon in any way.
Non virtual classes have no need for vtables as far as i know.
Reading your question it seems as if you think that each object has its own copy of the code, I'm not sure and i don't want to accuse you of anything like that but just in case ...
Google something like: "what does a c++ object look like in memory"
There will be one vtable somewhere in memory, probably in the same place as the code.
Each instance of the class will contain a single pointer to the vtable for that class, so in your case all 25 instances will contain a pointer to one copy of the vtable.
Multiple and virtual inheritance complicate things, but the principle is the same.