C++ Review for Test 2: List of Concepts Covered
Arrays and Classes
Arrays of Objects
Arrays as member data
- Arrays can be member data of a class
- If the array isn't always full, use a tracking variable (to track how
many slots used)
- Good for building types that use arrays, but also add in safeties,
like boundary checking, in the member functions
Card game example and Array Techniques
- Array of Card objects embedded inside Deck class -- "has-a"
relationshipArray of Card objects embedded in Player class -- "has-a"
relationship
- arrays of objects (and use of dot-operator)
- tracking variable numCards (in Player class) to track
how many cards currently in hand
- tracking variable topCard (in Deck class) to index the deal
position
Dynamic Memory Allocation and Classes
Memory Allocation Categories
- Static -- compile time. size and types known in advance
- Dynamic -- run time. sizes and amounts can be set while program
running
Dynamic Allocation, Deallocation
Notation:
- Arrow operator -- like the dot operator, but for pointers
- p->Show(); is the same as (*p).Show(); where p
is a pointer, *p is the object, and Show() is a member function.
Dynamically resizing an array (application example):
- dynamically create a new array of the needed size (need another
pointer for this)
- copy the data from the old array to the new one (use a for-loop)
- delete the old dynamic array (keyword delete)
- change the pointer so that the new array has the right name
Using DMA inside a class
- Pointer(s) as member data
- Initalizing pointers in the constructor(s) -- null pointer, dynamic
allocation of space
- Using correct clean-up in destructor
- Other member functions (memory management tasks) with
allocation,deallocation
- Understand the difference between the structural layout of the object
(and attached dynamic storage) vs. the semantic interpretation of the
object
Phonebook database example - examples of dynamic allocation,
dynamic resizing of array, pass by address, destructor
Automatics (Copy constructor, assignment operator)
Automatic functions
Every class has these. If not user-provided, a default is built:
- Constructor
- Destructor
- Copy Constructor
- Assignment operator =
Important to note:
- Default version of constructor and destructor are empty
- Not every class has a "default constructor" (i.e. no params) -- only
if no constructor is provided)
- Default version of copy constructor and assignment operator make a "shallow
copy"
- Shallow copy -- pointers and references copied verbatim. They
end up pointing to same attached data
- Deep copy -- make copies of attached data as well (which is
external from the physical "object"
- When dynamic allocation is done from inside a class, deep copy
funtions are needed if copies of objects are to be allowed
Copy Constructor
Assignment operator
Strings -- C-strings vs. string objects
- Understand the implementation of c-style strings
- Understand the limitations and drawbacks of c-style strings
- Understand the use of classes in building a "string" type,
including:
- Internal implementation with character arrays
- Use of dynamic allocation for variable length strings
- Destructor, copy constructor, assignment operator (in the event of
internal dynamic allocation in the class
- operator overloads, and likely usage for strings
- Note: This section and discussion was provided largely as an example
helping illustrate dynamic allocation concepts in a useful class
context
Inheritance - The Basics
The Inheritance Relationship
-
"is-a" relationship
-
Base classes and derived classes (derived class inherits from the base
class)
-
represents idea of supertypes and subtypes (categories and sub-categories)
Declaring derived classes:
Format: class derivedName : public baseName
Protection levels:
- public and private have usual meanings
protected
-
new protection label for use in base/derived classes
-
members declared as protected can be accessed by the class itself and by
derived classes only
Constructors:
-
When a derived object is created, the base constructors run, too
-
constructor definitions run in top-to-bottom order. Base class constructor
first.
-
destructors run in reverse order (derived class first, base last)
Constructors with parameters:
-
For default constructors (no parameters), the derived class constructor
automatically calls the parent constructor
-
parameters can be passed when declaring a derived object.
-
parameters are distributed up to the base constructors through initialization
list (with explicit calls to the parent constructor)
-
Constructor bodies still run in normal order (base class first)
Defining Derived classes:
-
Derived classes inherit all data and functions from the base class
-
Can still write a new version of an existing base class function for the
derived class (function overriding)
-
i.e. both base and derived class can have their own version of a function
with the same prototype
-
can distinguish between them with class name and scope-resolution operator
Multiple inheritance
-
classes derived from more than one base class
-
Old versions of ifstream and ofstream are good examples
-
ifstream derived from istream and fstreambase
-
ofstream derived from ostream and fstreambase
Inheritance: Virtual Functions and Abstract Classes
Important Pointer Property
-
Pointers to base class types can point at derived objects
- Similarly, a base class reference variable can attach to a derived object
Examples of Benefits To the User
- Simplifies storage, putting many base pointers into one container.
- Example: heterogeneous list -- an array of base class pointers, each can
point to a different derived object
- Ability to write more versatile functions, with base pointer (or reference) parameters.
User can send pointers to various derived objects on the call.
Virtual functions:
-
base class function declared to be virtual (a keyword)
-
changes the binding of the call to the function definition from static
(compile time) to dynamic (run-time).
-
function marked as virtual is bound dynamically (run time)
-
Compiler can only make decision based on the type of the calling object
or pointer.
-
virtual is needed because of the pointer property (base pointer pointing
at derived object).
-
virtual function called through base class pointer -- derived version can
run.
Abstract Classes
-
" = 0 " on a function declaration means function will not be defined (makes
a virtual function into a "pure virtual" function)
-
A class with at least one pure virtual function is an abstract class.
-
An abstract class cannot be instantiated (cannot build an object of this
type).
polymorphism
-
with Object Oriented Programming, refers to the use of the base pointer to
child object property, along with virtual functions and function
overriding to make the appropriate calls
Example of these concepts found in Employee class example, as well as
the Shape example (and others) posted on the notes pages.
Bitwise Operators
Introduction
-
built-in operators that allow accessing and manipulating of individual
bits
-
necessary since smallest variables that can be created are at least 1 byte
-
accessing individual bits can be useful for making more efficient algorithms,
or using less storage space
The Bitwise Operators
-
&
-
bitwise AND. Performs the AND operation on individual bits (where
1 is true, 0 is false)
-
|
-
bitwise OR. Performs the OR operation on individual bits
-
^
-
bitwise exclusive OR. The result of XOR is true if there is exactly
one true (1) and one false (0).
-
<<
-
Left shift. Shifts the bits of a variable to the left
-
>>
-
Right shift. Shifts the bits of a variable to the right.
-
~
-
Complement. Reverses the bits of a variable (1's become 0's, and
vice versa).
Accessing individual bits
- Understand the concept of a bit mask and how to create one
- Understand how to do these basic operations on a single bit from a
variable, without changing or affecting the other bits stored in the
variable:
- Set a bit to 1
- Unset a bit (set to 0)
- Flip a bit to its opposite
- Query a bit (find out what it is -- 1 or 0)
- You should be able to identify or derive how the above operations are
done on a single bit -- with a combination of an appropriate operation and
a bit mask