Lecture 17
Last time, we left off on virtual
.
A C++ virtual function is a member function in the base class that you redefine in a derived class. It is declared using the virtual keyword. It is used to tell the compiler to perform dynamic linkage or late binding on the function.
We don’t need override
keyword, it just explicitly tells compiler to check if there is matching virtual method in base class.
This code executes Book:isheavy()
for Books, Text::isheavy()
for Texts and Comic::isheavy()
for comics.
The code acomodates multiple types under one abstraction(the Book abstraction) - polymorphism
Note: This is why our input operator rakes an istream &
but can operate on ifstream
, istringstreams
, etc.
Destructor Revisitd
so, destructing y runs into some problems:
Here, Y
’s destructor never runs. So memory leak. To prevent this, we need to make X
’s destructor virtual.
Now, this code no longer leaks.
Quick summary
- When dtor is not virtual, this only calls
X::~X()
, if it is virtual, thenY::~Y()
is called, as part destroying thatY
, its superclass component is destroyed andX
’s dtor runs as well - So, if you have inheritance, your destructor should ALWAYS BE VIRTUAL, even if the base class doesn’t have resources to manage, the derived classes later might.
- If no inheritance, no need for
virtual
Now, lets revisit student class:
There are two kinds of students, regular and co-op.
But, what should we put for Student::fees()
?
… Not sure:
- Every student should be regular or coop, there should be not student objects.
So, we do this in the student class:
- Here,
Student::fees()
is a pure virtual method, which is a method that does not require an implementation. A class with a pure virtual method is called a Abstract method and cannot be instantiated. - As long as there is ONE, pure virtual method, your class is Abstract
- e.g.
Student S; // error
The purpose of abstract classes is to define common interfaces and organize subclasses. Subclasses of an abstract class are also abstract unless they implement pure virtual methods.
Note:
- Abstract classes are called concrete
- In UML, visualize abstract classes and pure virtual methods by italicizing their name
Templates
Massive, but we’ll only going to go through only the basics
Now, lets revisit List as a template class
Note, that the above is exactly the same as the one learned before, but, insetad of having int
, we just changed it with a type T
, which can be anything.
So, HOWdo templates work? Roughly speaking, the compiler sees each initialization of the class (e.g. List<int>, List<List<int>>, etc
and generates specialized classes for each type declared.
TEMPLATE CODE MUST BE IN HEADER CLASS, CAN’T BE IN CC FILE
Compiler needs to know before linking, of the types T
can take. The restrictions on T
are what I, as the coder, make them.
This brings us to the STL (Standard Template Library)
- The STL is a large collection of useful templates
- Example: dynamic-length arrays
- Thank god, we can use vectors now
Now, consider the following:
Looping over vector:
We can also iterate in reverse:
Vectors are guaranteed to be implemented as arrays internally. Now that we have vectors, basically never use dynamic arrays again.
Many other vector operators are based off iterators, e.g. the erase method, which takes an iterator to the element you want to remove.
Be careful when using iterator and vectors. If we have an iterator pointing to data, and then we add something to the vec, the vec reallocates itself. But then, since we delete old array after copying it into a new one, iterator now points to invalid memory.
What are some ways we an initialize vectors?