Respected Sir!
please explain how c++ implements this dynamic binding a pictorial representation would be more useful in understanding perspective.
or suggest a websigt which contains pictorial representations and full detail about this topic.
let me paste some text for you, any vote is appreciated, :O
[20.2] How can C++ achieve dynamic binding yet also static typing?
When you have a pointer to an object, the object may actually be of a class that is derived from the class of the pointer (e.g., a Vehicle* that is actually pointing to a Car object; this is called "polymorphism"). Thus there are two types: the (static) type of the pointer (Vehicle, in this case), and the (dynamic) type of the pointed-to object (Car, in this case).
Static typing means that the legality of a member function invocation is checked at the earliest possible moment: by the compiler at compile time. The compiler uses the static type of the pointer to determine whether the member function invocation is legal. If the type of the pointer can handle the member function, certainly the pointed-to object can handle it as well. E.g., if Vehicle has a certain member function, certainly Car also has that member function since Car is a kind-of Vehicle.
Dynamic binding means that the address of the code in a member function invocation is determined at the last possible moment: based on the dynamic type of the object at run time. It is called "dynamic binding" because the binding to the code that actually gets called is accomplished dynamically (at run time). Dynamic binding is a result of virtual functions.
Related
My base class is called Account while the derived class Businessaccount has an additional int variable called x, as well as a getter-method (int getx()) for it.
Is slicing supposed to occur in the following situation? It obviously happens in my case:
vector<shared_ptr<Account>> vec;
shared_ptr<Businessaccount> sptr = make_shared<Businessaccount>();
vec.push_back(sptr);
After that, if I do this:
(*vec.at(0)).getx();
it says that class<Account> has no member named getx()!
I'd be thankful if somebody would tell me why this occurs and how to fix it.
(*vec.at(0)) is going to return an Account which doesn't know about x. You need to cast the Account pointer into a Businessaccount to reference that member.
shared_ptr<BusinessAccount> bA = dynamic_pointer_cast<BusinessAccount>(vec.at(0));
bA->getx();
No, slicing does not happen in this situation, your pointer is just converted to pointer to a base class ie your data is the same, just type of pointer is changed. When slicing happens you loose all data of derived class.
To solve the issue you either need to provide virtual method in base class that would be properly implemented in Businessaccount or use dynamic_cast or static_cast (if you are sure that object has type Businessaccount by different matter). Though using such cast is usually sign of not well designed program.
In C++ the static and dynamic type of an object pointed to can differ.
Your static type of what the shared pointers in that vec point to is Account.
The dynamic type of what the shared pointers in that vec point to varies. In your case, you put a Businessaccount in it.
When you want to access or call methods, you are given access to only the static type methods.
The static type is what you have proven to the compiler the type contains at that line.
If you know better, you can do a static_cast<Businessaccount*>(vec.at(0).get())->getx(). By doing so you are promising to the compiler that you have certain knowledge that the data at that location is actually a Businessaccount. If you are wrong, your program's behavior is undefined (if you are lucky you get a crash).
You can also use RTTI (run time type information) to ask if a particular object is a particular sub-type (in some cases, where the base class has a virtual method).
Account* paccount = vec.at(0).get();
Businessaccount* pba = dynamic_cast<Businessaccount*>(paccount);
if (pba)
pba->getx();
the above checks if the paccount is actually a Businessaccount*, and if so calls getx on it. If not, it does nothing.
Often dynamic casting is a sign you didn't design your object use properly; having to drill down past the interface into which implementation means maybe your interface wasn't rich enough.
In some scripting and bytecode compiled languages, they let you go off and call getx and proceed to crash/throw an exception/etc if that method isn't isn't there.
C++ instead lets you use what you have claimed to be there (via the type system), then lets you write your own handler if you want dynamic type checking.
I found below post
C++ polymorphism without pointers
that explains to have polymorphism feature C++ must use pointer or reference types.
I looked into some further resources all of them says the same but the reason .
Is there any technical difficulty to support polymorphism with values or it is possible but C++ have decided to not to provide that ability ?
The problem with treating values polymorphically boils down to the object slicing issue: since derived objects could use more memory than their base class, declaring a value in the automatic storage (i.e. on the stack) leads to allocating memory only for the base, not for the derived object. Therefore, parts of the object that belong to the derived class may be sliced off. That is why C++ designers made a conscious decision to re-route virtual member-functions to the implementations in the base class, which cannot touch the data members of the derived class.
The difficulty comes from the fact that what you call objects are allocated in automatic memory (on the stack) and the size must be known at compile-time.
Size of pointers are known at compile-time regardless of what they point to, and references are implemented as pointers under the hood, so no worries there.
Consider objects though:
BaseObject obj = ObjectFactory::createDerived();
How much memory should be allocated for obj if createDerived() conditionally returns derived objects? To overcome this, the object returned is sliced and "converted* to a BaseObject whose size is known.
This all stems from the "pay for what you use" mentality.
The short answer is because the standard specifies it. But are there any insurmountable technical barriers to allowing it?
C++ data structures have known size. Polymorphism typically requires that the data structures can vary in size. In general, you cannot store a different (larger) type within the storage of a smaller type, so storing a child class with extra variables (or other reasons to be larger) within storage for a parent class is not generally possible.
Now, we can get around this. We can create a buffer larger than what is required to store the parent class, and construct child classes within that buffer: but in this case, exposure to said instance will be via references, and you will carefully wrap the class.
This is similar to the technique known as "small object optimization" used by boost::any, boost::variant and many implementations of std::string, where we store (by value) objects in a buffer within a class and manage their lifetime manually.
There is also an issue where Derived pointers to an instance can have different values than Base pointers to an instance: value instances of objects in C++ are presumed to exist where the storage for the instance starts by most implementations.
So in theory, C++ could allow polymorphic instances if we restricted it to derived classes that could be stored in the same memory footprint, with the same "pointer to" value for both Derived and Base, but this would be an extremely narrow corner case, and could reduce the kinds of optimizations and assumptions compilers could make about value instances of a class in nearly every case! (Right now, the compiler can assume that value instances of a class C have virtual methods that are not overridden elsewhere, as an example) That is a non trivial cost for an extremely marginal benefit.
What more, we are capable of using the C++ language to emulate this corner case using existing language features (placement new, references, and manual destruction) if we really need it, without imposing that above cost.
It is not immediately clear what you mean by "polymorphism with values". In C++ when you have an object of type A, it always behaves as an object of type A. This is perfectly normal and logical thing to expect. I don't see how it can possible behave in any other way. So, it is not clear what "ability" that someone decided "not to provide" you are talking about.
Polymorphism in C++ means one thing: virtual function calls made through an expression with polymorphic type are resolved in accordance with the dynamic type of that expression (as opposed to static type for non-virtual functions). That's all there is to it.
Polymorphism in C++ always works in accordance with the above rule. It works that way through pointers. It works that way through references. It works that way through immediate objects ("values" as you called them). So, it not not correct to say that polymorphism in C++ only works with pointers and references. It works with "values" as well. They all follow the same rule, as stated above.
However, for an immediate object (a "value") its dynamic type is always the same as it static type. So, even though polymorphism works for immediate values, it does not demonstrate anything truly "polymorphic". The behavior of an immediate object with polymorphism is the same as it would be without polymorphism. So, polymorphism of an immediate object is degenerate, trivial polymorphism. It exists only conceptually. This is, again, perfectly logical: an object of type A should behave as an object of type A. How else can it behave?
In order to observe the actual non-degenerate polymorphism, one needs an expression whose static type is different from its dynamic type. Non-trivial polymorphism is observed when an expression of static type A behaves (with regard to virtual function calls) as an object of different type B. For this an expression of static type A must actually refer to an object of type B. This is only possible with pointers or references. The only way to create that difference between static and dynamic type of an expression is through using pointers or references.
In other words, its not correct to say that polymorphism in C++ only works through pointers or references. It is correct to say is that with pointers or references polymorphism becomes observable and non-trivial.
How can C++ achieve dynamic binding yet also static typing?
When you have a pointer to an object, the object may actually be of a class that is derived from the class of the pointer (e.g., a Vehicle* that is actually pointing to a Car object; this is called "polymorphism"). Thus there are two types: the (static) type of the pointer (Vehicle, in this case), and the (dynamic) type of the pointed-to object (Car, in this case).
Static typing means that the legality of a member function invocation is checked at the earliest possible moment: by the compiler at compile time. The compiler uses the static type of the pointer to determine whether the member function invocation is legal. If the type of the pointer can handle the member function, certainly the pointed-to object can handle it as well. E.g., if Vehicle has a certain member function, certainly Car also has that member function since Car is a kind-of Vehicle.
Dynamic binding means that the address of the code in a member function invocation is determined at the last possible moment: based on the dynamic type of the object at run time. It is called "dynamic binding" because the binding to the code that actually gets called is accomplished dynamically (at run time). Dynamic binding is a result of virtual functions.
I'm not talking about a pointer to an instance, I want a pointer to a class itself.
In C++, classes are not "first class objects". The closest you can get is a pointer to its type_info instance.
No. A pointer is the address of something in the memory of the computer at run-time. A class is just a set of instructions to the compiler.
As everyone else have already said, it's not possible to have a pointer to a class.
But if the point is to create a new instance from some class chosen at runtime, you might want to check out the Factory Method (or Abstract Factory) design patterns.
Yes and No. This depends on your context of what you are trying to achieve. If you simply want a pointer to a type then no there is not a way. A type does not live in memory in the sense of a pointer.
There reason I said yes though is some people would consider the virtual table a pointer to a type. It is possible to get this pointer since the virtual table does exist in memory and can be used to invoke virtual methods with a bit of trickery.
Unlike true Object-Based languages, a class is not an object in C++, more is the pity. The closest you can come to "pointer to class" is RTTI:
const std::type_info &info = typeid(object expression);
type_info has name() member finction, and they can be compared to each other.
A "Class" does not exist. The only thing you can point to is the data.
The rest of a "Class" is actually a dispatch table. For each method in the class, the dispatch table has a pointer. That way, the class points to the correct method of your class regardless of what type it's currently cast to. This would be useless to access.
Methods in your class (the things pointed to by the dispatch table) are actually just "Functions" that are passed in your class data pointer. The definition of a method is pretty much that it's a function that takes the classes data as a parameter. In most C-style languages, that data pointer is hidden but referred to as "this".
The methods for your class may be spread all over the codebase. Because of parent classes, you're not likely even find these methods adjacent to each other.
You can't have a (run-time) pointer to a class, but C++ does has a similar compile-time concept: template parameters. Boost has a library dedicated to manipulating them and a traits library for getting information about classes.
Depending upon how you want to think about pointers, you can have a "pointer" to a class, if by pointer you mean some integral value. Boost allows you to register types and assign a unique integer for every type that you register. If the types you are registering are all classes then you can look up at run-time the code necessary to create an object of the type you want, as long as you have the value of the type you want. But in general, classes aren't first class objects in the language and the best you can hope for is to simulate the behavior you want to have.
True, there is no support for reflection/introspection in built in to C++, but there are a number of libraries that will add many of eg java's Class functionality, and allow a programmer to get an object representing a class, create an instance, etc. google c++ reflection.
I need some clarification on dynamic binding in C++ .I'm confused about the following:
In C you can have an array of function pointers & assign different functions of the same signature & call them based on the index; is this Dynamic binding?
In C++ you can have an array of base class pointers but you can call different functions of the derived class, by assigning the derived class objects addresses to a base-class array of pointers & by using virtual functions, Is this Dynamic Binding?
Which term is correct - Dynamic binding or Link-Time Binding?
Answers
No. This is much closer to dynamic dispatch than dynamic binding. Dynamic binding refers to the way in which a named method is bound at runtime. There is no name here.
Yes. If the methods are virtual then this is the definition of dynamic binding. The name is known at compile time but the method called cannot be determined without knowing the runtime object type
I'm not sure what you mean here. Dynamic binding is the more idiomatic term.
I'd call both of these uses of dynamic binding. In C++, the language is giving you the mechanism, so that you don't have to roll your own as you do in C.
(I once worked with an app in which every major object was passed around accompanied by a struct whose fields were function pointers. The struct's purpose was to allow the app to implement run-time dynamic binding -- that is, to change the assigned functions for the object at runtime, depending on the object's state. This "feature" was never taken advantage of, so far as I know.)
Dynamic binding is binding interface to its implementation at runtime - any situation when the program automatically decides which code to call as interface implementation. So generally speaking both 1) and 2) are dynamic binding, but the term is usually only used for 2).
Link-time binding (aka early binding) is the opposite of dynamic binding (aka late binding). In link-time binding the compiler/linker knows exactly what code to call and gererates a direct call of that code. In dynamic binding the compiler/linker doesn't know that - exact implementation is determined at runtime.
Have you tried writing a code In C language? Which compiler you used for this? You can't have two functions with same name in C language.
You're confusing the concept of dynamic binding with the implementation. Dynamic binding, i.e. choosing which method to call based on the receiving object's type, may be implemented using some form of dynamic dispatch, i.e. your (1), but we generally define the name to only refer to situation (2).