Virtual Function and Override Keyword
Virtual Function
In C++, a virtual function is a member function that is declared in a base class and can be overridden by a derived class. When a virtual function is called on an object, the actual function that is called depends on the type of the object, not the type of the pointer or reference used to call the function.
Virtual function should be declared in public
section of the class.
class Foo {
public:
virtual void bar { // this is a virtual function.
std::cout << "virtual bar" << std::endl;
}
}
Then what is a pure virtual function
? A pure virtual function is a virtual function that has no implementation in the base class and is meant to be overridden in all derived classes.
class Foo {
public:
virtual void bar = 0; // this is a *pure* virtual function.
}
virtual function
: allows derived classes to provide specific implementations that will be called when a function is invoked on a base class pointer or reference.pure virtual function
: makes the class abstract, meaning it cannot be instantiated on it's own and requires derived classes to provide an implementation for the pure virtual function.
Early Binding v.s. Late Binding
Binding | Also Known As |
---|---|
Early | static binding or compile time binding |
Late | dynamic binding or runtime binding |
Early binding a used for non-virtual functions, where the function to be called is determined at compile-time.
class Animal {
public:
void skeap() {
std::cout << "animal speak" << std::endl;
}
}
class Dog : public Animal {
void speak() {
std::cout << "Dog speak" << std::endl;
}
}
int main() {
shared_ptr<Animal> animal = make_shared<Dog>();
animal->speak(); // output : animal speak
shared_ptr<Dog> dog = make_shared<Dog>();
dog->speak(); // output : animal speak
return 0;
}
Late binding is used for virtual functions, where the function to be called is determined at run-time.
class Animal {
public:
virtual void speak() {
std::cout << "animal speak" << std::endl;
}
}
class Cat {
public:
void speak() override {
std::cout << "cat speak" << std::endl;
}
}
int main() {
shared_ptr<Animal> animal = make_shared<Cat>();
animal->speak(); // output: cat speak
shared_ptr<Cat> cat = make_shared<Cat>();
cat->speak(); // output: cat speak
return 0;
}
Pros and Cons
Method | Performance | Flexibility |
---|---|---|
Early binding | Look up speed fast π | Determined at compile timeπ |
Late binding | look up speed slow π | Polyphormism π |
Override Keyword
The override
keyword is an identifier that specifies that a member function is intended to override a virtual function in a base class. It's a feature to help catch common programming errors at compile time.
class Base {
public:
virtual void display() = 0;
}
class Derived : public Base {
public:
void display() override {
std::cout << "display in derived" << std::endl
}
};
The keyword provides several benefits:
safety
: it ensures that the function is indeed overriding a virtual function in the base class.readability
: it makes the programming's intent clear.maintenance
: it helps during refactoring or modifying the code, as any changes that might break the overriding functionality will be caught at compile time.
Virtual Function in Class
Abstract Class
An abstract class is a class containing at least
one virtual function. But if the abstract class only have one
virtual function, this class is called pure abstract class
.
class Base {
public:
virtual void virt() = 0;
};
class Derived : public Base {
public:
void virt() {
// implementation of virt()
std::cout << "It's derived from virt()" << std::endl;
}
};
Interface Class
An interface class
is a class containing a list of virtual function without any other member variables or member functions. It's derived class should implement all of these virtual functions.
class IShape {
public:
virtual void getArea() = 0;
virtual void getParameters() = 0;
};
Comparison
Kind | Has Virtual Function | Has Memeber Variables | Can Be Instantiated |
---|---|---|---|
Abstract class | yes, at least one | β | β |
pure abstract class | yes, only one | β | β |
interface class | yes, at least one | β | β |