Function Hiding
If you have a function with the same name (even with different parameters) in a derived class, it will hide
the function in the base class (without the virtual
keyword).
Example hiding :
//hiding5.cpp
#include <iostream>
class Base {
public:
virtual void fun(int i, int j) const { std::cout << "Base " << i << " " << j << std::endl; }
};
class Derived: public Base {
public:
void fun(char c) const {std::cout << "Derived" << i << " " << j << endl;}
};
int main() {
Derived d;
d.fun(76, 77); // Derived 76 77
d.Base::fun(76, 77) // Base 76 77
((Base&) d).fun(76, 77) // Derived 76 77
((Base) d).fun(76, 77) // Base 76 77
}
- Specify
Base::fun
to chose the scope of it and compile over there - Use dynamic dispatch by casting
d
as a reference withBase&
to treat it as as a memory layout of the base class. It will call the derived class version because we have thevirtual
function. - Simple casting will call the base class version.
Pure virtual
functions
class Shape {
public:
virtual double size() const = 0;
...
};
- Declaring a
virtual
member function and adding=0
means it is a purevirtual
function. - In memory layout, it means to set the address of the virtual function to
nullptr
.
When we declare a pure virtual
function:
- Do not give it a implementation
- Make the class its declared in an abstract class.
- We cannot create a new object with this type, though we might be able to create an object from a derived
type (if they provide an implementation for all the pure
virtual
functions). - When a class has one or more pure virtual functions, it cannot be instantiated; it is abstract.
Abstract Classes
A class is abstract if it has at least one pure virtual function or has only non-public constructor.
- Variables cannot be of abstract type
- Similar to abstract class and interface in Java
- We can have pointers and references of abstract class types but not concrete objects (cannot be instantiated)
- If we do not override the pure virtual functions in derived class, then derived class also becomes abstract class
- An abstract class can have constructors
Another way to make a class abstract is give it only non-public constructors.
- Can't instantiate the abstract class because constructor cannot called from the outside. Derived class can still use protected constructor in base class.
Example:
class Piece {
public:
...
protected:
// this is the only constructor
Piece (bool is_white): is_white(is_white) { }
...
private:
bool is_white;
};
class Queen: public Piece {
...
// Queen constructor calls Piece constructor
// OK because it's protected
Queen(bool is_white): Piece (is_white) { }
...
};