Difference Between a Virtual Function and a Pure Virtual Function

Difference between a virtual function and a pure virtual function

A virtual function makes its class a polymorphic base class. Derived classes can override virtual functions. Virtual functions called through base class pointers/references will be resolved at run-time. That is, the dynamic type of the object is used instead of its static type:

 Derived d;
Base& rb = d;
// if Base::f() is virtual and Derived overrides it, Derived::f() will be called
rb.f();

A pure virtual function is a virtual function whose declaration ends in =0:

class Base {
// ...
virtual void f() = 0;
// ...

A pure virtual function implicitly makes the class it is defined for abstract (unlike in Java where you have a keyword to explicitly declare the class abstract). Abstract classes cannot be instantiated. Derived classes need to override/implement all inherited pure virtual functions. If they do not, they too will become abstract.

An interesting 'feature' of C++ is that a class can define a pure virtual function that has an implementation.
(What that's good for is debatable.)


Note that C++11 brought a new use for the delete and default keywords which looks similar to the syntax of pure virtual functions:

my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;

See this question and this one for more info on this use of delete and default.

What is the difference between virtual function and pure virtual function in C++ in when both not defined in base class?

So in both situation, derived class must define the display function

Incorrect. Only pure virtual functions must be overridden by a derived class in order for that derived class to be concrete.

So why should we need pure virtual function?

To specify that a type is abstract, which prevents it's instantiation.

What is the difference between virtual function and pure virtual function in C++ in when both not defined in base class?

A pure virtual function is something that makes a class abstract, as I mentioned.

By declaring a function, you promise that there will be a definition for it. If there is no definition, then the program is ill formed. Pure virtual functions are exceptions in that it's not mandatory to define them (but you may). So in short, a non pure virtual without a definition is a bug.

Is there any difference between a private and protected pure virtual function?

Are there any scenarios where a protected pure virtual makes any
sense?

I think that you mean private here (instead of protected), but think I understand your point. In fact, the access type of a pure virtual can be overridden in derived classes. Here's an example that might help you see the difference between a private and protected pure virtual:

class Parent
{
protected: virtual void foo() = 0;
private: virtual void bar() = 0;
public: void test() { foo(); bar(); }
};

class Child : public Parent
{
public: void test2() { foo(); /* bar(); // cannot be called here */ }
};

class GrandChild : public Child
{
// access types here can be anything for this example
public: void foo() { cout << "foo" << endl; }
public: void bar() { cout << "bar" << endl; }
};

What's the difference between Virtual functions and normal functions?

#include <iostream>

class A {
public:
void Y() { std::cout << "A" << std::endl; }
virtual void X() { std::cout << "A" << std::endl; }
};

class B : public A {
public:
void Y() { std::cout << "B" << std::endl; }
virtual void X() { std::cout << "B" << std::endl; }
};

int main() {
A a;
a.Y(); // "A"
a.X(); // "A"

B b;
b.Y(); // "B"
b.X(); // "B"

A* ap = &b;
ap->Y(); // "A"
ap->X(); // "B"
}

Virtual functions are not that interesting if you're not into polymorphy and deriving. As you see, in the third case the instance of B is accessed via a pointer of type A*. With non-virtual functions this means that functions called are actually defined in A, not in B. Virtual function calls are resolved with a table, so the code at runtime determines where to jump.

To your questions:

1) Determining at runtime, which function is to be called, depending on the real type of the object.

2) Polymorphy

3) No, as ap->X() would call A::X() if it were not for virtual.

4) With pleasure:

void MakeMeASandwich(); default, nothing special.

virtual void MakeMeASandwich(); a virtual function, providing an implementation. Deriving classes may choose to override it.

virtuall void MakeMeASandwich() = 0; a virtual function is declared, but no implementation is provided. The class containing this function is automatically set to be abstract and can't be instantiated.

Virtual/pure virtual explained

From Wikipedia's Virtual function
...

In object-oriented programming, in languages such as C++, and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. This concept is an important part of the (runtime) polymorphism portion of object-oriented programming (OOP). In short, a virtual function defines a target function to be executed, but the target might not be known at compile time.

Unlike a non-virtual function, when a virtual function is overridden the most-derived version is used at all levels of the class hierarchy, rather than just the level at which it was created. Therefore if one method of the base class calls a virtual method, the version defined in the derived class will be used instead of the version defined in the base class.

This is in contrast to non-virtual functions, which can still be overridden in a derived class, but the "new" version will only be used by the derived class and below, but will not change the functionality of the base class at all.

whereas..

A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class if the derived class is not abstract.

When a pure virtual method exists, the class is "abstract" and can not be instantiated on its own. Instead, a derived class that implements the pure-virtual method(s) must be used. A pure-virtual isn't defined in the base-class at all, so a derived class must define it, or that derived class is also abstract, and can not be instantiated. Only a class that has no abstract methods can be instantiated.

A virtual provides a way to override the functionality of the base class, and a pure-virtual requires it.

Pure virtual function vs. virtual function?

I wouldn't decide that now. Later you could make an abstract base class for Tree and move code there, if that made sense.

Another option to inheritance for this kind of thing is a pointer-to-function or functor type to call. It's a lot easier to reuse, because you don't have to keep making new classes for each new situation.

C++ difference between virtual = 0; and empty function

For your

class SomeClass{
virtual void aMethod()=0;
}

the presence of a pure virtual method makes your class abstract. Once you have one such pure virtual method, =0, in your class, you cannot instantiate the class. What is more, any derived class must implement the pure virtual aMethod(), or it becomes an abstract class as well.

In your derived class, you overwrite the pure virtual method from above, and this makes the derived class non abstract. You can instantiate this derived class.

But, in derived class, method's body is empty, right? That's why your question makes sense: why not make the class pure virtual as well. Well, your class may entail other methods. If so, SomeClass cannot be instantiated (there is a pure virtual method), whereas child class SomeClassSon can be.

Same applies to your AnotherClass, which can be instantiated, contrary to SomeClass.

Why does it make sense to give definition for a pure virtual function?

"we are saying that the function cannot have any definition for the class where this pure virtual function is declared."

That's not what pure virtual means. Pure virtual only means that the containing class cannot be instantiated (is abstract), so it has to be subclassed, and subclasses must override the method. E.g.,

struct A {
virtual ~A() = 0;
};

A::~A() {}

struct B : A {};

int main()
{
A a; // error
B b; // ok
}

Here, the B destructor is implicitly defined. If it was another method that is pure virtual, you'd have to explicitly override it:

struct A {
virtual void foo() = 0;
};

void A::foo() {}

struct B : A {};

int main()
{
B b; // error
}

Providing a definition for a pure virtual method is desirable when the base class must be abstract but still provide some default behavior.

In the specific case of a destructor, it has to be provided because it will be called automatically when subclass instances are destroyed. A program that tries to instantiate a subclass of a class with a pure virtual destructor without a definition will not pass the linker.



Related Topics



Leave a reply



Submit