I'm a little familiar with C++, but the virtual keyword still confuses me. What exactly does it mean? If a function is defined as virtual, is that the same as pure virtual?
"Virtual" means that the method may be overridden in subclasses, but has an directly-callable implementation in the base class. "Pure virtual" means it is a virtual method with no directly-callable implementation. Such a method must be overridden at least once in the inheritance hierarchy -- if a class has any unimplemented virtual methods, objects of that class cannot be constructed and compilation will fail.
@quark points out that pure-virtual methods can have an implementation, but as pure-virtual methods must be overridden, the default implementation can't be directly called. Here is an example of a pure-virtual method with a default:
#include <cstdio>
class A {
public:
virtual void Hello() = 0;
};
void A::Hello() {
printf("A::Hello\n");
}
class B : public A {
public:
void Hello() {
printf("B::Hello\n");
A::Hello();
}
};
int main() {
/* Prints:
B::Hello
A::Hello
*/
B b;
b.Hello();
return 0;
}
According to comments, whether or not compilation will fail is compiler-specific. In GCC 4.3.3 at least, it won't compile:
class A {
public:
virtual void Hello() = 0;
};
int main()
{
A a;
return 0;
}
Output:
$ g++ -c virt.cpp
virt.cpp: In function ‘int main()’:
virt.cpp:8: error: cannot declare variable ‘a’ to be of abstract type ‘A’
virt.cpp:1: note: because the following virtual functions are pure within ‘A’:
virt.cpp:3: note: virtual void A::Hello()
"A virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature" - wikipedia
"A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class that is not abstract" - Wikipedia
So, the virtual function can be overriden and the pure virtual must be implemented.
Also, a good link for questions like this is http://www.parashift.com/c++-faq-lite/
In an C++ class, virtual is the keyword that designates that a method can be overridden (i.e. implemented by) a subclass. For example:
class Shape
{
public:
Shape();
virtual ~Shape();
std::string getName() // not overridable
{
return m_name;
}
void setName( const std::string& name ) // not overridable
{
m_name = name;
}
protected:
virtual void initShape() // overridable
{
setName("Generic Shape");
}
private:
std::string m_name;
};
In this case a subclass can override the the initShape function to do some specialized work:
class Square : public Shape
{
public:
Square();
virtual ~Square();
protected:
virtual void initShape() // override the Shape::initShape function
{
setName("Square");
}
}
The term pure virtual refers to virtual functions that need to be implemented by a subclass and have not been implemented by the base class. You designate a method as pure virtual by using the virtual keyword and adding a =0 at the end of the method declaration.
So, if you wanted to make Shape::initShape pure virtual you would do the following:
class Shape
{
...
virtual void initShape() = 0; // pure virtual method
...
};
By adding a pure virtual method to your class you make the class an abstract base class which is very handy for separating interfaces from implementation.
Read the answers above for the semantics. I will try to explain the notion of "virtual" and "pure virtual" in English so you can remember:
- "Virtual" means it is there "virtually." Like virtual reality, you can sort of touch and feel it but you can also easily manipulate it.
- "Pure Virtual" is just pure fiction! It's not there at all (as indicated by assignment to zero). It's doesn't exist.
Hope this helps.
The virtual keyword gives C++ its' ability to support polymorphism. When you have a pointer to an object of some class such as:
class Animal
{
public:
virtual int GetNumberOfLegs() = 0;
};
class Duck : public Animal
{
public:
int GetNumberOfLegs() { return 2; }
};
class Horse : public Animal
{
public:
int GetNumberOfLegs() { return 4; }
};
void SomeFunction(Animal * pAnimal)
{
cout << pAnimal->GetNumberOfLegs();
}
In this (silly) example, the GetNumberOfLegs() function returns the appropriate number based on the class of the object that it is called for.
Now, consider the function 'SomeFunction'. It doesn't care what type of animal object is passed to it, as long as it is derived from CAnimal. The compiler will automagically cast any CAnimal-derived class to a CAnimal as it is a base class.
If we do this:
Duck d;
SomeFunction(&d);
it'd output '2'. If we do this:
Horse h;
SomeFunction(&h);
it'd output '4'. We can't do this:
Animal a;
SomeFunction(&a);
because it won't compile due to the GetNumberOfLegs() virtual function being pure, which means it must be implemented by deriving classes (subclasses).
Pure Virtual Functions are mostly used to define:
a) abstract classes
These are base classes where you have to derive from them and then implement the pure virtual functions.
b) interfaces
These are 'empty' classes where all functions are pure virtual and hence you have to derive and then implement all of the functions.
I'd like to comment on Wikipedia's definition of virtual, as repeated by several here. Wikipedia defines a virtual method as one that can be overridden in subclasses. That is incorrect: any method, not just virtual ones, can be overridden in subclasses. What virtual does is to give you polymorphism, that is, the ability to select at run-time the most-derived override of a method.
Consider the following code:
#include <iostream>
using namespace std;
class Base {
public:
void NonVirtual() {
cout << "Base NonVirtual called.\n";
}
virtual void Virtual() {
cout << "Base Virtual called.\n";
}
};
class Derived : public Base {
public:
void NonVirtual() {
cout << "Derived NonVirtual called.\n";
}
void Virtual() {
cout << "Derived Virtual called.\n";
}
};
int main() {
Base* bBase = new Base();
Base* bDerived = new Derived();
bBase->NonVirtual();
bBase->Virtual();
bDerived->NonVirtual();
bDerived->Virtual();
}
What is the output of this program?
Base NonVirtual called.
Base Virtual called.
Base NonVirtual called.
Derived Virtual called.
Derived overrides every method of Base: not just the virtual one, but also the non-virtual.
We see that when you have a Base-pointer-to-Derived (bDerived), calling NonVirtual calls the Base class implementation. This is resolved at compile-time: the compiler sees that bDerived is a Base*, that NonVirtual is not virtual, so it does the resolution on class Base.
However, calling Virtual calls the Derived class implementation. Because of the keyword virtual, the selection of the method happens at run-time, not compile-time. What happens here at compile-time is that the compiler sees that this is a Base*, and that it's calling a virtual method, so it insert a call to the vtable instead of class Base. This vtable is instantiated at run-time, hence the run-time resolution to the most-derived override.
I hope this wasn't too confusing. In short, any method can be overridden, but only virtual methods give you polymorphism, that is, run-time selection of the most derived override. In practice, however, overriding a non-virtual method is considered bad practice and rarely used, so many people (including whoever wrote that Wikipedia article) think that only virtual methods can be overridden.
Simula, C++, and C#, which use static method binding by default, the programmer can specify that particular methods should use dynamic binding by labeling them as virtual. Dynamic method binding is central to object-oriented programming.
Object oriented programming requires three fundamental concepts: encapsulation, inheritance, and dynamic method binding.
Encapsulation allows the implementation details of an abstraction to be hidden behind a simple interface.
Inheritance allows a new abstraction to be defined as an extension or refinement of some existing abstraction, obtaining some or all of its characteristics automatically.
Dynamic method binding allows the new abstraction to display its new behavior even when used in a context that expects the old abstraction.