Function Hiding and Abstract Classes

Created

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 with Base& to treat it as as a memory layout of the base class. It will call the derived class version because we have the virtual 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 pure virtual 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) { } 
	...
};