I was asked this interview question today!! (it was a really awkward telephonic interview..):
What is the difference between the vtable for a class with virtual
functions and a class with pure virtual functions?
Now, I know the C++ standard doesn't specify anything about vtables, or even the existence of a v-table ..however theoretically speaking what would the answer be?
I blurted out that the class with a pure virtual function could have a vtable and its vtable entry for the pure virtual function will point to the derived class implementation. Is this assumption correct? I did not get a positive answer from the interviewer.
Will a hypothetical compiler create a vtable for a class with only pure virtual functions? What if the class contains pure virtual functions with definitions? (as shown in : http://www.gotw.ca/gotw/031.htm).
In the case of non-pure virtual functions, each entry in the vtable will refer to the final-overrider or a thunk that adapts the this pointer if needed. In the case of a pure-virtual function, the entry in the vtable usually contains a pointer to a generic function that complains and aborts the program with some sensible message (pure virtual function called within this context or similar error message).
Will a hypothetical compiler create a vtable for a class with only pure virtual functions?
Yes, it will, the difference will be in the contents stored in the table, not in the shape of the table. In a simplistic approach, a NULL pointer for pure virtual functions, non-NULL for virtual functions. Realistically, a pointer to a generic function that will complain and abort() with usual compilers.
What if the class contains pure virtual functions with definitions?
This will not affect the vtable. The vtable is only used for dynamic dispatch, and a call will never be dynamically dispatched to the definition of a pure virtual function (i.e. you can only manually dispatch to the pure virtual function by disabling dynamic dispatch qualifying the name of the type: x.base::f() will call base::f even if it is pure-virtual, but x.f() will never be dispatched to base::f if it is pure virtual.
An implementation can do pretty much anything in such cases, because if
your code ends up calling a pure virtual function in a context where
dynamic resolution is required, and it would resolve to a pure virtual
function, the behavior is undefined. I've seen several different
solutions: the compiler inserts the address of a function which
terminates with an error message (the preferred solution from a
quality of implementation point of view), the compiler inserts a null
pointer, or the compiler inserts the address of the function from some
derived class. I've also seen cases where the compiler will insert the
address of the function if you provide an implementation. The only
correct answer to the question is that you can't count on any particular
behavior.
I can tell you that "pure" abstract classes (classes with only pure virtual functions) are used by Microsoft (and MS VC++) for their COM interfaces. Perhaps he was speaking of it. The "internal" representation of a COM is a pointer to a vtable. Pure abstract classes in MS VC++ are implemented in the same way, so you can use them to represent COM objects. Clearly if you class has other virtual functions, you can't simply overwrite its vtable with the COM vtable :-)
Related
Do interfaces (polymorphic class solely with pure virtual functions) have a vtable?
Since interfaces do not implement a polymorphic function themself and cant be directly constructed there would be no need for the linker to place a vtable. Is that so? Im especially concerned about the MSVC compiler.
Yes, they do. And there are a number of good reasons for that.
The first good reason is that even pure virtual methods have implementation. Either implicit or explicit. It is relatively easy to pull off a trick calling a pure virtual function, so you can basically provide a definition for one of yours, call it and see what happens. For that reason, there should be a virtual table in a first place.
There is another reason for putting a virtual table into a base class even if all of its methods are pure virtual and there are no other data members though. When polymorphism is used, a pointer to a base class is passed all around the program. In order to call a virtual method, compiler/runtime should figure out the relative offset of the virtual table from the base pointer. If C++ had no multiple inheritance, one could assume a zero offset from the abstract base class (for example), in which case it would have been possible not to have a vtable there (but we still need it due to reason #1). But since there is a multiple inheritance involved, a trick ala "vtable is there at 0 offset" won't work because there could be two or three vtables depending on a number (and type) of base classes.
There could be other reasons I haven't though of as well.
Hope it helps.
From a purely C++ point of view it's an academic question. Virtual functions don't have to be implemented with vtables, if they are there is no portable way to get at them.
If you're particular concerned about the MSVC compiler you might want to decorate your interfaces with __declspec(novtable).
(In general, in common implementations, an abstract class may need a vtable, e.g.:
struct Base {
Base();
virtual void f() {}
virtual void g() = 0;
};
void h(Base& b) {
b.f(); // Call f on a Base that is not (yet) a Derived
// vtable for Base required
}
Base::Base() {
h(*this);
}
struct Derived : Base {
void g() {}
};
int main() {
Derived d;
}
)
The vtable is not necessary, but rarely optimized out. MSVC provides the __declspec(novtable) extension, which tells the compiler explicitly that the vtable can be removed. In the absence of that, the compiler would have to check itself that the vtable is not used. This is not exceptionally hard, but still far from trivial. And since it doesn't provide real speed benefits in regular code, the check is not implemented in any compiler I know.
Does every class have virtual function table in C++?
I know virtual table is for polymorphism. Class with virtual functions must have v-table. But how about class has no virtual function? Or how about class has no base class?
The language specification of C++ does not define what a "vtable" is, or which classes need one.
A particular implementation of C++ in a compiler often uses a vtable to implement virtual methods. If a class has no virtual methods (and no superclasses with virtual methods), then the compiler may omit the vtable. However, keep in mind this is purely a compiler implementation decision, and not required by the standard.
As a non-standard rule of thumb (vtables are not dictated by the standard) which applies to virtually all compilers:
Only classes with virtual member functions and/or a virtual destructor have a vtable. Other classes not. This conforms to the general rule in C++ "pay for what you use".
Of course this puts you into an important responsibility: Is your class to be deleted polymorphically? I.e., will it be used as a public base class and be deleted through it? Then make the destructor virtual.
C++ language as such doesn't talk about how virtual functions needs to be implemented i.e. it can using vtables or any other mechanism. Having said that, generally it is implemented using v-table, and this v-table is created only if the class contains virtual functions.
v-table holds the function's address in it. This table will hold the function address of all the virtual functions that are defined in the base class.
Based on the actual object type, this address changes and the exact function is called.
If the class does not inherits any of the class with virtual function, it need not hold any v-table. All the functions calls will be linked compile time.
How does Virtual Method Invocation work in C++?
Through virtual tables.
Read this article, http://en.wikipedia.org/wiki/Virtual_table.
I could explain it here, but the wikipedia does a better job than I could.
The C++ standard doesn't specify how the virtual function mechanism should be implemented.
That said, I think all current C++ compilers use virtual tables.
The common way to do this for classes which contain at least one virtual function to have a hidden pointer to a so-called virtual table, where the addresses of the virtual functions for a specific class are entered in compiler-specific order.
Each constructor will then set this hidden pointer to the virtual table of the class it belongs to.
Every class with at least one virtual method has it's virtual table - table of pointers to functions that are that class's methods.
It's extensively used in COM.
With VTables and function pointers. Virtual functions' function pointer will be listed in VTable
MFC is using Message Map instead of Virtual function, which reduces the size limitation. If we use several virtual function VTable will end up with big size.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why pure virtual function is initialized by 0?
In C++, what does it mean to set a function declaration to zero? I'm guessing it has to do with the function being virtual, and not actually defined in this class. Found in a header file of code that I'm reading:
virtual void SetValue(double val)=0;
What's going on here?
It's a pure virtual function. It makes it so you MUST derive a class (and implement said function) in order to use it.
This is called a pure virtual member function in C++ lingo. It means, as you guessed, that the function is not defined within the class, but rather has to be implemented in deriving classes. You cannot instantiate classes with pure virtual member functions, pure virtual functions basically behave like abstract methods in Java or C#.
It means that it is a pure virtual method - which means subclasses must implement the method on their own. There can still be an implementation for that method, but classes with pure virtual methods cannot be instantiated, making this similar to the abstract keyword seen in various other languages.
if you set a virtual function to set, Its called Pure Virtual Functions. And then your class becomes an abstract class.
You can't create instances of that class or any subclasses unless your pure virtual functions are implemented.
The method SetValue is pure virtual. Its class does not provide the implementation of that method, and can not be instantiated (therefore we term it abstract). Concrete derived classes on the other hand have to provide implementations for such methods. See more here.
It means that, the class is abstract, and can't be create its object. It could be used as a base class to another. Pure virtual class is also used in c++ as an interface known from language like java, but of course it is different.
As everyone has mentioned, this means that the function is a pure virtual function. Think of of this as setting the function pointer to null. Classes with pure virtual functions are handled as abstract classes. This means that derived classes must implement this virtual function.
Occasionally, you may encounter what is called a "pure call" error. This means that a pure virtual function was actually called and it will most likely cause the program to crash. The most common cause of a pure call is that the object that the function was called on was already deleted.
"SetValue" is a pure virtual member function that the base class forces derived classes to provide. Pure virtual member functions will have no implementation.
A pure virtual member function specifies that a member function will exist on every object of a concrete derived class even though the member function is not (normally) defined in the base class.
This is because the syntax for specifying a pure virtual member function forces derived classes to implement the member function if the derived classes intend to be instantiated (that is, if they intend to be concrete).
In your case, all objects of classes derived from the base class will have the member function SetValue(). However, because the base class is an abstract concept, it does not contain enough information to implement SetValue().
Imagine that the "= 0" is like saying "the code for this function is at the NULL pointer."
Pure virtual member functions allow users to write code against an interface for which there are several functionally different variants. This means that semantically different objects can be passed to a function if these objects are all under the umbrella of the same abstract base class.
Do we have virtual table for an abstract class?
First of all, usage of vtables is implementation defined and not mandated by the standard.
For implementations that use vtable, the answer is: Yes, usually. You might think that vtable isn't required for abstract classes because the derived class will have its own vtable, but it is needed during construction: While the base class is being constructed, it sets the vtable pointer to its own vtable. Later when the derived class constructor is entered, it will use its own vtable instead.
That said, in some cases this isn't needed and the vtable can be optimized away. For example, MS Visual C++ provides the __declspec(novtable) flag to disable vtable generation on pure interface classes.
There seems to be a common misconception here, and I think traces of its sources can still be found online. Paul DiLascia wrote sometime in 2000 that -
...see that the compiler still
generates a vtable all of whose
entries are NULL and still generates
code to initialize the vtable in the
constructor or destructor for A.
That may actually have been true then, but certainly isn't now.
Yes, abstract classes do have vtables, also with pure abstract methods (these can actually be implemented and called), and yes - their constructor does initialize the pure entries to a specified value. For VC++ at least, that value is in the address of the CRT function _purecall. You can in fact control that value, either by overloading purecall yourself or using _set_purecall_handler.
We have a virtual table for a class which has atleast one virtual function.
that virtual function can also be pure.
this means. an abstact class can have a vtable.
in case of abstact classes the vtable entry will be NULL.
when ever you try to instantiate a abstract class it will check in tha vtable and check for a NULL value is present or not.
if NULL is present the compiler will throw an error.