If I define a class like this:
class A{
public:
A(){}
virtual ~A(){}
virtual void func(){}
};
Does it mean that that the virtual destructor and func
are inlined
Whenever a virtual function is called using base class reference or pointer it cannot be inlined, but whenever called using the object without reference or pointer of that class, can be inlined because the compiler knows the exact class of the object at compile time.
The only situation in which a function cannot be inlined is if there is no definition for the function in the compilation unit. Even that will not prevent link-time inlining by a link-time optimizer.
Base classes can't inherit what the child has (such as a new function or variable). Virtual functions are simply functions that can be overridden by the child class if the that child class changes the implementation of the virtual function so that the base virtual function isn't called. A is the base class for B,C,D.
A virtual function cannot be global or static because, by definition, a virtual function is a member function of a base class and relies on a specific object to determine which implementation of the function is called. You can declare a virtual function to be a friend of another class.
Whether the compiler chooses to inline a function which is defined inline is entirely up to the compiler. In general, virtual
functions can only be inlined when the compiler can either prove that the static type matches the dynamic type or when the compiler can safely determine the dynamic type. For example, when you use a value of type A
the compiler knows that the dynamic type cannot be different and it can inline the function. When using a pointer or a reference the compiler generally cannot prove that the static type is the same and virtual
functions generally need to follow the usual virtual dispatch. However, even when a pointer is used, the compiler may have enough information from the context to know the exact dynamic type. For example, MatthieuM. gave the following exmaple:
A* a = new B;
a->func();
In this case the compiler can determine that a
points to a B
object and, thus, call the correct version of func()
without dynamic dispatch. Without the need for the dynamic dispatch, func()
could then be inlined. Of course, whether compilers do the corresponding analysis depends on its respective implementation.
As hvd correctly pointed out, the virtual dispatch can be circumvented by calling a virtual function will full qualification, e.g., a->A::func()
, in which case the virtual function can also be inlined. The main reason virtual functions are generally not inlined is the need to do a virtual dispatch. With the full qualification the function to be called is, however, known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With