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
Derivedclass 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 baseclass. 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 |