A pure-virtual function is not unlike a virtual function, except that you needn't provide a default implementation like you must do with a virtual function. But whether a generic implementation is provided or not, the class is rendered abstract, which means you cannot instantiate the class directly -- you must derive a new class. Indeed, the only reason for declaring a pure-virtual function is to render the class abstract.
Why would you design a class that cannot be instantiated other than by derivation? There are many reasons, but ultimately the class is intended to represent a conceptual object rather than an actual object. A conceptual object is a generic object that encapsulates everything that is common to all its derivatives, but one that cannot provide a complete implementation of its interface.
For instance, circles and squares are actual objects that share a common concept: they are both types of shape. Thus circles and squares (and all other shapes) may be derived from a generic shape object. The shape object can encapsulate everything that is common to all shapes, such as colour attributes, line width and style, and so on. It can also provide common interfaces such as draw(), rotate() and so on. But it cannot implement these interfaces without knowing what type of shape it actually is. While you could use expensive runtime type information within the base class to determine the type of shape and write reams of base class code with switch statements to cater for all possible shapes, this makes no sense (and would be a maintenance nightmare) when the derivatives have all the information required to implement these interfaces. Thus the abstract shape class exists to provide a common interface while each specific shape fills in the details and provides the actual implementation.
The derivative must provide an implementation for the pure-virtual method (augmenting or replacing any generic implementation, where one exists) otherwise it becomes abstract itself. But once a derivative implements a pure-virtual function, the function becomes a normal virtual function with respect to any of its derivatives. That is, derived implementations can be inherited, but the base class implementation (if one exists) cannot be inherited.
A pure-virtual function is declared like any other virtual function, by prefixing the function with the virtual keyword. The difference is that you must append =0 after the function signature:
class abstract
{
public:
virtual void my_function()=0;
};
If a generic function body is require, it can be declared externally:
void abstract::my_function()
{
// ... function body goes here
}
Or it can be declared inline:
class abstract
{
public:
virtual void my_function()=0{ /* ... function body goes here */ }
};
Chat with our AI personalities
All virtual functions (including pure-virtual functions) are represented in italics. All non-virtual functions are represented normally. There is no differentiation between pure and non-pure virtual functions, however some people append "=0" to distinguish the pure-virtual functions.
Virtual Functions and Pure Virtual Functions are relevant in the context of class inheritance.Unlike Virtual Functions, Pure Virtual Functions do not require a body. This implies that when a base class defining such a function is inherited, the derived class must implement that function. Furthermore, the base class becomes abstract; meaning you cannot create an instance of the base class even if a body is implemented for the function. You are expected to derive from abstract classes; only the derived classes that implement all the inherited Pure Virtual functions can be instantiated.Here are some examples of Virtual and Pure Virtual function signatures:- Virtual Function: E.g. virtual void myFunction();- Pure Virtual Function: E.g. virtual void myFunction() = 0;
Inherit is not a function. It is a class derivation where some of the methods and attributes of the new class inherit from a parent class.
A virtual function is a member function of a class, whose functionality can be over-ridden in its derived classes. It is one that is declared as virtual in the base class using the virtual keyword. The virtual nature is inherited in the subsequent derived classes and the virtual keyword need not be re-stated there. The whole function body can be replaced with a new set of implementation in the derived class
AnswerA virtual function must be declared as a non-static member method of a class that you expect to act as a base class. Declaring a virtual function adds some overhead as a result of creating the v-table (virtual method table), but most of that overhead is paid with the first virtual function (subsequent virtual functions just add a new entry to the already-existing v-table). However, do not declare a virtual function unless you expect that function to be overridden. Bear in mind that overriding an overloaded, non-virtual function "hides" all the overloads in the base class.If a virtual function must be overridden, declare it as pure-virtual instead. You do not need to implement the method in the base class, but you will be reminded to provide an implementation in the derived class at compile time if one does not exist, even if you provide a default implementation in the base class. Bear in mind that base classes with one or more pure-virtual methods become abstract -- they cannot be instantiated.If there is any virtual function or pure-virtual function, there must also be a virtual destructor, as well as a public or protected default constructor (a constructor with no arguments). When a derived class is constructed, it calls the base class constructor, which calls its base class constructor. Derived classes are constructed in sequence, beginning with the least-derived class. Destruction is the reverse -- the most-derived class is destroyed before the base classes are destroyed.Virtual functions can be invoked just like any other class member method, both via an object reference's member operator (.), and the indirection operator (-->) for pointers to objects. It does not matter whether the reference or pointer refers to a base class or a derived class; the v-table decides which override (where one is provided) will actually execute, starting from the most-derived override and working back towards the base class, the least-derived. With appropriate use of virtual functions, dynamic casting can be avoided completely (dynamic casting should never be employed as it completely defeats the point of having a v-table in the first place).