specifier override to indicate intention to override
Assume that you want override the Fish::Swim
in Derived
class but with a slightly different signature - one using const
inserted unintentionally like the following
1 | class Tuna: public Fish |
this function actually does not override Fish::Swim()
. Therefore, override
supplies a powerful way of expressing the explicit intention to override a base class virtual function, thereby getting the compiler to check whether:
- the base class function is virtual
- the signature of the base class virtual function exactly matches that of the
Derived
class function declared to override.
using final
to prevent function overriding
A class declared as final
cannot be used as a base class, similarly, a virtual function declared as final
cannot be overridden in a derived class.
:
1 | class Tuna: public Fish |
class Tuna
in this snippet can be inherited from, but Swim()
cannot be overridden any further.
virtual copy constructors
c++ does not allow usage of virtual copy constructors.
Having said that, there is a nice workaround in the form of defining your own clone function that allow you to do that:
1 | class Fish |
the this
pointer
The this
pointer is a pointer accessible only within the nonstatic member functions of a class
, struct
, union
type. It points to the object for which the member function is called.
:
1 | this |
The this
pointer's type can be modified in the function declaration by keywords const
and volatile
. To declare a function that has either of these attributes, add the keywords after the function argument list.
consider an example:
1 | class Point |
The preceding code declares a member function X()
, in which the this
is treated as a const
pointer to a const
object.
Go ahead with virtual function clone, it's a simulated virtual copy constructor that needs to be explicitly invoked.
e.g. A clone function as a simulated virtual copy constructor demolist11_9
1 |
|
output
1 | new Tuna(*this) 0x55ad513c1320 |
Comparing line 17 with line 65 and line 66, the address of new Tuna
is expected to be allocated, whereas, the three have difference store address as the output line 1,2,3 demonstrates. myFish[0]
get a address by using new Tuna()
in line 57 before we call myFish->Clone()
in line 64 of main
. Therefore, myNewFish()
is allocated to a address as well while calling. Line 18 can be interpreted as:
1 | Base* X= new Base; |
as the preceding snippet demonstrates, argument Y
is a representation of myNewFish()
, and X
is the transit.
Additionally
[Why we can do : Base base = new Derived; while we can not do Derived derived = new Base?]
Remember mark functions in derived classes that are intended to override base functionality using keyword overridden
.
QAbstract base classes and pure virtual function.
- a base class that cannot be instantiated is called an
abstract base
class. It fullfils only one purpose, that of being derived from.- e.g.
virtual void BaseFunc () = 0;
: Given an inheritance hierarchy, do I need to use the keyword virtual
on all declarations of a virtual function or just in the base class.
: It is enough to declare a function as virtual
once, but that declaration has to be in the base class. As long as a class has at least one pure virtual function, it remains an abstract base class(ABC) irrespective of the presence or absence of other fully defined functions or parameters.
exercise
Bug busters
Q:what is the problem in the following code:
1 | class Vehicle |
: doesn't have a virtual destructor. That can cause only one(car
or vehicle
) destructor invoked when it goes out of scope. e.g.
1 | Vehicle* pMyRacer = new Car; |
In this case nonvirtual destructor would result in only ~Vehicle
invoked.
Correction
1 | class Vehicle |