C++ midterm review
COMP 345 C++ midterm review
C++ midterm review
Slide Set 1:
1. program structure
C++ is a superset of C
- Main function is the program driver
- Free functions
- Data structures
- A C program is valid C++ program
Classes encapsulate other functions: Object-oriented
The main function is a free function, not a class member
Only simplistic programs are self-contained into one file
- C++ is a language that specifies programming structures and includes only
basic data structures and operators - Most programs require the use of libraries
- Complier will compile the library’s code and the program’s code, then
the linker will link them - Unlike Java, a single C++ file can contain many classes/functions/data
structures. - This leads to what is called
physical design
, i.e. decisions as to what entities are grouped within/across files.
- C++ is a language that specifies programming structures and includes only
multiple files programs Aside from having to use libraries, large programs need to be split into different files for various reasons:
- Speed up compilation: Upon changes to the code, the compiler will recompile only the files that had a change.
- Increase organization, decrease browsing time: Physically splitting your code along logical lines will make it easier to browse through the code to locate classes, functions, etc.
- Facilitate code reuse: Modular physical design allows for grouping related entities and separating them from less related ones. Each group can then be logically designed to be reusable across different projects. Reused code can be fixed, fixing all projects that use it.
- Split coding responsibilities among programmers: For really large projects, several programmers are involved. The larger are the program files, the more likely it is that several programmers are changing the same file simultaneously.
2. compilation unit
In C++, a compilation unit is a file (
.cpp
)A file may contain several functions, data structures, or classes (unlike Java)
Each compilation unit is compiled individually into an object file
The object files typically have cross-references to other object files
The linker then attempts to resolve cross-references between the object files to form the unique executable file.
Each component is a group of
highly cohesive
andhighly coupled
elementsCohesion: The degree to which the elements of a module belong together in the achievement of a common goal.
Cohesion is increased if:
- The functionalities embedded in a module have much in common.
- The composing elements carry out a small number of related activities, by avoiding coarsely grained and/or unrelated sets of data.
Advantages of
high cohesion
:- Increased
understandability
of modules (simpler, fewer operations). - Increased
maintainability
, because changes in one module require fewer changes in other modules. - Increased
reusability
, because application developers will find the component they need more easily among the cohesive set of operations provided by the module.
- Increased
Coupling: the degree to which an element relies on other elements for its operation
- Coupling is not a desired quality, but is a side-effect of defining different elements to carry a common task
- Much related to cohesion: good modules exhibit
high cohesion
andhigh coupling
- Coupling between modules is what really needs to be avoided
Disadvantages of high coupling:
- A change in one module forces a ripple effect of changes in other modules
- Assembly of modules requires more effort due to the increased inter-module
dependency - A module might be harder to reuse and/or test because dependent modules must be included
3. header/cpp files
header File (
.h
file)- Contains class declaration with
free functions
andoperators declarations
- Useful to programmers, as it is overview of a component that omits
implementation details
- Contains class declaration with
Source File (
.cpp
file)- Contains free/member function definitions
- The
.cpp
file is a compilation unit
General rules:
- There should be a one-to-one relationship between a given
.cpp
file and a corresponding.h
file, and they should have the same name. - The
.cpp
file “#includes
” its corresponding.h
file. - A
.cpp
file should never be “#included
”, as it effectively merges two compilation units together.
- There should be a one-to-one relationship between a given
cpp
files contain the executable code, i.e. function definitions- Function definitions:
- Functions -
main()
function, free functions, member functions - Operators - free operators, member operators
- Functions -
- Function definitions:
4. includes
- Two types to use
#include
#include "mymodule.h"
- Quotes indicate a user-defined module
- The compiler will find it in your project directories
#include <mymodule.h>
< >
indicate predefined libraryheader
file- The compiler will find it in the library directories
- Using different search paths
5. redundant includes
Use preprocessor directives
- Instructs the compiler to read a header file only once
two ways for
fname.h
:1
2
3
4
5
6
...
//Content of header file
...#pragma once
6. namespaces
Namespace: Collection of name definitions inside of a program, potentially across different files
For example, namespace “std” is common in libraries. Has all standard library definitions we need
1
2
using namespace std;- Includes entire standard library of name definitions
1
2
3
using std::cin;
using std::cout; - Can specify just the objects we want
- Can be more efficient, as it avoids including things we don’t use
- Includes entire standard library of name definitions
This is one reason why the use of using
NS::name
directive is advocated over usingnamespace NS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17{
using namespace NS1;
myFunction();
}
{
using namespace NS2;
myFunction();
}
//or
{
using NS1::MyFunction();
myFunction();
}
{
using NS2::MyFunction();
myFunction();
}global namespace
- All code goes in some namespace
- Unless specified, code belongs to the global namespace
- No need for using directive
- Global namespace always available
- But there is no way to “turn it off”
- Thus, global namespace is prone to name clashes
the same namespace needs to be declared in both
.h
and.cpp
files1
2
3
4
5
6
7
8
9
10
11
12
13// In the header file
namespace Space1
{
void greeting();
}
//In the implementation file (definitions):
namespace Space1
{
void greeting()
{
cout << "Hello from namespace Space1.\n";
}
}global vs. unnamed namespace
1
2
3
4
5
6
7
8
9
10
11
12
13
using namespace std;
namespace {
const int i = 4; // this is local
}
int i = 2; // this is global
int main() {
cout << i << endl; // ERROR, i is ambiguous
return 0;
}
Slide Set 2:
1. structs and classes as data types
User-defined data types using
struct
(as in C), as well asclass
(object-oriented programming)- Both are allowed in the same program
- In fact, they are almost equivalent, but
struct
was kept for backward compatibility - A
struct
can have data members, methods, constructors, destructors, etc - One difference is that a
struct
sets its members aspublic
by default
2. variable initialization
Declarations can include an optional initialization, which can use different syntactical forms:
1
2
3
4Type a1 {v};
Type a2 = {v};
Type a3 = v;
Type a4(v);All of these are widely used and apparently equivalent.
However:
- Some are restricted to use in certain situations.
- Only the first one is universally usable, and is actually safer, as it implicitly does some checking of the value passed versus the specified type.
1
2int a1 = 1.5; //allowed using truncation
int a1 {1.5}; //not allowed, as type checking is enforced
Default initialization: variable is constructed with no initializer.
1
2
3
4
5//For basic types, the previous value held in the memory space is kept.
//For objects, the default constructor is called.
int x;
std::string s;
classA *objAv1 = new classA;Value initialization: variable is constructed with an empty initializer.
1
2
3
4
5//For basic types, the value is zero-initialized.
//For objects, each member is value-initialized.
int x{};
std::string s{};
classA objA = classA();Direct initialization: variable is constructed using explicit constructor arguments.
1
2
3
4
5//For basic types, no constructors, but constructor call syntax can be used.
//For objects, the corresponding constructor is called
int x(4);
std::string s("hello");
classA objA(value1,value2,value3);Copy initialization: Variable is created using the value(s) from an existing object of the same type, or uses a converting sequence if available. Applies only to named objects.
1
2
3std::string s = "hello";
classA objAv1; classA objAv2(objAv1);
classA objAv3 = objAv1;- Copy initialization is implicitly used when passing and returning objects by value.
List initialization: Initializes an object from a braced initialization list.
1
2
3std::string s{'a', 'b', 'c'};
int n1{1}; // direct-list-initialization
int n2 = {1}; // copy-list-initializationReference initialization: Binds a reference to an object.
1
2char& c = a[0]
int i1; int& iref = &i1;- Reference initialization is used implicitly when a value is passed by reference or a reference is returned from a function.
Aggregate initialization: Initializes an aggregate from braced initialization list. It is list initialization but applied to aggregates.
- Simply stated, an
aggregate
is either:- an
array
- an
object
of aclass
that hasonly public members
andno constructors
- Definition of an aggregate varies between standards.
1
2
3
4
5
6
7
8
9
10
11
12
13char a[3] = {'a', 'b'};
int i[3] = {1,2,3};
class aggrB{
int x, y;
}
class aggrA{
int a, b, c;
aggrB b;
}
aggrA a1 = {1,2,3,{4,5}};
- an
- Simply stated, an
3. implicit/explicit type coercion
- type coercion: implicitly or explicitly changing the type of variables or values, and this makes C++ a weakly typed language.
int var = 2.99; // 2 is assigned to var!
static_cast, dynamic_cast
- Different kinds of Explicit type casting
1
2
3
4
5
6
7
8
9
10
11
12static_cast<Type>(expression)
//General-purpose type casting
static_cast<double>(intVar)
const_cast<Type>(expression)
//Cast-out “constantness”
dynamic_cast<Type>(expression)
//Runtime-checked conversion of pointers and references within a single class hierarchy. Used for downcasting from a superclass to a subclass
reinterpret_cast<Type>(expression)
//Implementation-dependent casting, performs a binary copy and assigns the new type to the resulting binary copied value. Highly unsafe and error-prone.
* upcasting/downcasting
static_cast
makes a static (compile-time) type cast, but correct runtime behavior cannot be verified.Use
dynamic_cast
to downcast into a subclassdynamic_cast
works onpointers
Does runtime checking to verify that the cast is successful
Also deals with polymorphic types and virtual methods at runtime
4. conversion sequences
Two things can be used in a conversion sequence:
conversion constructor: a constructor that takes a value of a type and creates an object of another type.
A::A(int){...}
conversion operator: a member operator that has the name of a type.
A::operator int(){...}
If you don’t want your constructors or operators to be used in a conversion sequence, you have to declare them as
explicit
in the class declarationexplicit B(int);
explicit operator bool() const;
5. pointers
A pointer variable contains the memory address of a portion of memory that in turn contains a specific value.
1
2
3int i = 99;
int* p = &i;
cout << *p << endl;Two operators on pointers:
- Dereferencing operator:
*
, e.g.*p
refers to the object pointed to by the pointer. - Address operator:
&
, e.g.&i
refers to the address of the first memory cell holding a value.
- Dereferencing operator:
pointer assignment:
p1 = &v1;
,p2 = p1;
value assignment:
*p2 = *p1;
If pointers are declared in a function
- The pointer is managed as a local variable
- The value pointed to is dynamically allocated/deallocated,
allocated with
new
operator, deallocated wih thedelete
operator.Allocated on the
heap
(also known asfreestore
) through the runtime system’s interaction with the operating system.1
2
3
4
5int *p;
p = new int(5); //allocate memory
... //Some processing...
delete p; //deallocate memory
p = NULL; //prevents dangling pointer errors
6. pointer artithmetic
- Can perform arithmetic operations on pointers
- Used to navigate arrays (covered later)
1
2int *d;
d = new int[10]; d
refers to: `address of new int[10]``d + 1
refers to:address of new int[10] + 1*sizeof(int)
(Note: type of int is 4 bytes, so sizeof(int) is 4 bytes.)d + 2
refers to:address of new int[10] + 2*sizeof(int)
d[i] == *(&d[0]+i) == *(d+i)
7. pointers and const
- two sepatate meanings/usages of const
- Specify the constantness of the pointer
- Specify the constantness of the value pointed to.
1
2
3
4
5
6
7int x;
int * p1 = &x; // non-const pointer to non-const int
const int * p2 = &x; // non-const pointer to const int
int * const p3 = &x; // const pointer to non-const int
const int * const p4 = &x; // const pointer to const int
8. void/wild/dangling/null pointers
void pointer: a pointer that is allowed to be pointing to a value of any type.
- disadvantage: need to cast them specifically in order to use them.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// void* data
void increase (void* data, int psize){
if ( psize == sizeof(char) ){
char* pchar; pchar=(char*)data; ++(*pchar); }
else if (psize == sizeof(int) ){
int* pint; pint=(int*)data; ++(*pint); }
}
int main (){
char a = 'x';
int b = 1602;
increase (&a,sizeof(a));
increase (&b,sizeof(b));
cout << a << ", " << b << '\n';
return 0;
}
- disadvantage: need to cast them specifically in order to use them.
wild pointer: a pointer that points to an arbitrary memory location.
- This is most often due to an
uninitialized pointer
declaration - like
int *x;
- This is most often due to an
wild pointer can lead:
Segmentation fault:
- pointing to an address that is not accessible by the program’s process
- pointing to an address that contains read-only data
Arbitrary value:
- pointing to a valid address that contains a valid but arbitrary integer value
dangling pointer: a pointer that used to point to a valid memory area, that has now been potentially reassigned to another usage.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int* func(){
int num = 1234; // num is local to func
return # // func returns pointer to num
}
void func(){
ClassA *objA = new ClassA();
delete(objA); // *objA is deallocated
// objA is now a dangling pointer
// Dereferencing will still appear
// to work, until the memory is used
// for something else
}null pointer: a pointer that points nowhere
int* x = nullptr;
int* y = NULL;
int* z = 0;
- Dereferencing a null pointer is a compilation error : safer pointer usage.
Pointers should be initialized as
null
pointers.Dangling pointers
should be assigned tonull
.Check for null pointer is then a good way to know if a pointer is
valid
or not.
* stack/heap/new/delete
* arithmetics
9. references
A reference is in fact an “alias” for a memory space.
Terminology: the reference is an
alias
to a referent (the value pointed to).Both the
reference
and thereferee
represent the same value/object.such as
int& r{v1};
, return&r
references are often used to
pass parameters
or evenreturn a value
.
10. smart pointers (NO)
11. parameter passing
- Parameters can be passed to a function:
- by value
- by pointer
- by reference
- cannot pass
NULL
, as a reference cannot beNULL
- cannot pass
12. strings
- two types:
- C-style character strings
char greeting[6]={'H','e','l','l','o','\0'};
terminated by\0
(a null character)char greeting[] = "Hello";
<cstring>
string
class type introduced with Standard C++
- C-style character strings
Slide Set 3:
1. input/output streams
C++ uses streams for input/output.
C++ programs can also use C-style input/output, which don’t use streams.
Streams are objects that are defined to handle a device on which input or output operations are performed.
Streams allow C++ programs to interact with external entities controlled by the operating system,
- such as:
- program execution console
- keyboard
- files
- such as:
Other external entities such as network sockets are not provided by basic C++ stream classes, but are available in various libraries (e.g. Boost).
2. cin/cout
I/O stream objects
cin
,cout
,cerr
Defined in the C++ library called
<iostream>
Must have these lines (pre-processor directives) :
1
2
using namespace std;cout
is an object that is an instance of theostream
class, defined in theiostream library
.cout
is a stream,<<
is the stream insertion operator that is used to output to the stream.Any data can be
outputted
to astream
- Variables
- Constants
- Literals (eg. string)
- Results of expressions
Stream manipulators
- set output specially-formatted numbers
1
2cout << fixed << showpoint << setprecision(2);
//show exaclty 2 digits after the decimal point: 78.50
- set output specially-formatted numbers
keyboard input stream
- use
cin
for input from the keyboard - use
>>
(stram extraction operator) cin >> num
(right-hand-side must be a variable)
- use
3. files stream declarations, open/close, usage
Similar to
cin/cout
streams, there are streams for input/output from/to files- File input :
ifstream
- File output :
ofstream
- Part of library
<fstream>
- use
<<
operator towrite
- use
>>
operator toread
- File input :
output:
1
2
3
4
5
6
7//1
ofstream outputfilestream;
outputfilestream.open("scores.txt");
//2
ofstream outputfilestream("scores.txt");
//
outputfilestream.close();input:
1
2
3
4
5ifstream inputfilestream;
infilestream.open("scores.txt");
//or
ifstream inputfilestream("scores.txt");
inputfilestream.close();fsteram
object akso be used, but need to specifyfile modes
, such asios::out
1
2
3
4
5
6
7
8fstream filestream;
filestream.open("scores.txt“, ios::out);
//output operations
filestream.close();
//do other things
filestream.open("scores.txt“, ios::in);
//input operations
filestream.close();file modes:
ios::in
Opens a file for input.ios::out
Opens a file for output.ios::app
Appends all output to the end of the file.ios::ate
Opens a file for output. If the file already exists, move to the end of the file. Data can be written anywhere in the file.ios::trunc
Discards the file’s contents if the file already exists. (This is the default action for ios:out).ios::binary
Opens a file for binary input and output.
some examples:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28ofstream output;
// Create/open a file
output.open("scores.txt");
// Write two lines
output << "John" << " " << "T" << " " << "Smith" << " " << 90 << endl;
output << "Eric" << " " << "K" << " " << "Jones" << " " << 85 << endl;
// Close the file
output.close();
//
//
ifstream input("scores.txt");
string firstName, lastName; char mi; int score;
input >> firstName >> mi >> lastName >> score;
cout << firstName << " " << mi << " " << lastName << " " << score << endl;
input >> firstName >> mi >> lastName >> score;
cout << firstName << " " << mi << " " << lastName << " " << score << endl;
input.close();
//OR
string firstName, lastName; char mi; int score;
ifstream input("scores.txt");
input >> firstName >> mi >> lastName >> score;
while (!input.eof()) {
cout << firstName << " " << mi << " " << lastName << " " << score << endl;
input >> firstName >> mi >> lastName >> score;
}
input.close();stream states and functions
eof()
returnstrue
if theeofbit
flag is set.fail()
returnstrue
if thefailbit
orhardfail
flag is setbad()
returnstrue
if thebadbit
flag is setgood()
returnstrue
is thegoodbit
flag is setclear()
clear all stream state flagsios::eofbit
set when the end of an input stream is reachedios::failbit
set when an operation on the stream has failedios::hardfail
set when an unrecovered error has occurredios::badbit
set when an invalid operation has been attemptedios::goodbit
set if none of the preceding bits is set
4. << and >> operator overloading
- To enable a
user-defined type
to be outputted to a stream, the<<
operator must be overloaded to accept this type as an operand.
5. MFC serialization (NO)
Slide Set 4:
1. classes vs. structs
As
classes
are an expandedstruct
, it is also possible to declare and use a struct that includes member functions, and that even inherits from another struct, just like classes.The only difference between
class
andstruct
is that the members of astruct
arepublic
by default, butprivate
by default for aclass
.A
struct
that does not use object-oriented features is nicknamed a POD for “plain old data structure”.
2. struct usage
Once the
struct
has been declared, it can be used as any other typeThe members of a struct can be referred to using the
dot
notation1
2
3
4
5
6
7
8
9
10
11
12
13
14struct CDAccount1
{
double balance;
double interestRate;
int term;
}
int main()
{
CDAccount1 account;
double interestRate;
interestRate = account.interestRate/100.0;
}
3. class declarations (.h and .cpp files)
A
Class
is an Abstract Data TypeA C++ class represents an abstract data type by allowing functions to be
syntactically encapsulated
into its definition, along with its data elements.The syntax of a
class
definition is the same as for astruct
.
4. declaring/using objects
Variables of a class type are referred to as
objects
.Objects are declared using the same syntax as for basic types.
1
2DayOfYear today;
DayOfYear *birthday = new DayOfYear();Class types
can be used anywhere a type can be used:- As type of a variable
- As parameter to a function
- As a return type to a function
- As a value pointed to by a pointer
Members of a class are referred to using the dot notation and their access is regulated by the
private
,public
andprotected
access specifiers.
* with or without pointers
- The members of an object can be referred to using the dot notation:
1
2
3int day1 = today.getDay();
int day2 = *birthday.getDay(); // equivalent
int day3 = birthday->getDay(); // equivalent - kinds of methods
Accessor
: method whose goal is to expose a value in the state of an object, generally the value of a particular data member.Mutator
: method whose goal is to change a value in the state of an object.Service method
: method that exposes some service or desired behavior to other classes/objects.Internal behavior methods
: methods that are used by the class/object itself internally, that defines some of its behavior that should not be triggered explicitly from the exterior. These methods should thus beprivate
.Constructor
: method whose goal is to manage the operations to be performed as an object is created.Destructor
: method whose goal is to manage the operations to be performed as an object is destroyed.
5. inline functions/methods
A function (or method) can be declared as
inline
, meaning that its entire code is to be replacing any call to this function.Function inlining aims at execution
optimization
by eliminating the function call mechanism overhead.However, it has the disadvantage of leading to
code bloat
if the body of the inline function contains a large amount of code and/or is consuming a large amount of memory and is called frequently at different places in the code.To define a function as inline, one needs to include the
inline
keyword as a prefix to the function definition. The function declaration does not need to have theinline
prefix.In other words, inline functions have internal linkage. If you want to make an inline function accessible to other compilation units, they must include the definition of the inline function.
Note that declaring a function/method as inline is only a hint for the compiler, and that the compiler may choose not to inline a function if it is not possible, e.g. for recursive functions.
Rule of thumb
: Inline your functions that havevery short
function definitions. Accessor methods are very good candidates for method inlining.
6. const specifier
- Specifies that its subject is constant, i.e. that its value cannot be changed after it is set. Can be applied to:
Variables
: A variable may be declared asconst
, which signifies that its value cannot be changed after it is initialized. It assumes that the variable is initialized upon declaration.1
const DayOfYear newYearDay(1,1);
Function parameters
: Declaring a function parameter asconst
means that the value of this parameter cannot be changed by the execution of1
2
3
4int max(const int i1, const inbt i2)
{
return i1 >= i2 ? i1 : i2;
}Methods
: Declaring a method asconst
means that this function will not alter the state of the object to which it belongs. By extension, only methods declared asconst
can be called on an object that was itself declared asconst
upon declaration.1
2
3
4int DayOfYear::getDay() const
{
return day;
}
Pointers
involve two different concepts- the pointer itself
- the value pointed to
7. static specifier
A member of a class can be declared as
static
, which means that this member is a class member, i.e. it belongs to the class as a whole an can be called on the class rather than on the objects.If it is a data member, its value is unique across all objects of the class, i.e. it is a “class global variable”.
If a member function is declared as
static
, it can only use other members that are also declared asstatic
.Used to define state and behavior that is independent of any particular object’s state instantiated from this class.
Static
member variables are generally initialized outside of the class declaration. Only constant static integral members can be initialized inside of the class declaration. The initialized value must be a constant expression.Other languages allow static classes (e.g. C#), which C++ does not have.
Non-member variables can also be declared as
static
, which has a slightly
different meaning:- When you declare a variable or function at file scope the
static
keyword specifies that the variable or function has internal linkage, i.e. it cannot be referred to outside of the compilation unit in which it is declared. - When you declare a local variable to a function as
static
, the variable has static duration, i.e. its value is kept even when the execution goes out of the scope of this function. In other words, it is a “global variable that has local scope to this function”.
- When you declare a variable or function at file scope the
All
static
variables persist from thestart
of the execution of the program until the programterminates
.Non-static member
functions canaccess
all data members of theclass
:static
andnon-static
.static
member functions can only operate on thestatic
data members, or call otherstatic
member functions.
8. friends
In principle,
private
andprotected
members of a class cannot be accessed from outside the class in which they are declared.A
friend
(function or class) of a class mayaccess
the members designated asprivate
orprotected
.Friends are functions/methods or classes declared as such within a class.
Friends are not members, so they are not inherited from a superclass.
9. constructors/destructors
To sum-up, variables allocated on the
stack
aredestroyed
as we get out of the block’s scope, but objects allocated on theheap
usingnew
need to be manually destroyed usingdelete
.Rule of thumb: for every
new
, there should be a correspondingdelete
somewhere.if you
define
your own constructor(s), make sure that you provide
adefault constructor
, as the default constructor is likely to be called implicitly by the runtime system.* declaration/implementation
* initialization list
* implicit/explicit constructor calls
* call chain
Destructors
are called in the exactreverse order
as theconstructors
.
10. inheritance
more
flexible
andextensible
designA
base class
is a class from which other classes inherit from.- Often called a
super-class
, or a parent or ancestor class.
- Often called a
A
derived class
is a class that inherits from a base class.- Often called a
sub-class
, or a child or descendent class. - Data Members
- Member functions
- not inherit
- constructors, copy constructors
- assignment operator
- destructor
- Often called a
Multiple inheritance
is when a derived class inherits from more than one base class.An
abstract class
is a class that is meant to be derived from by containing abstract member functions that do not have a definition, assuming that they will find a concrete implementation in a derived class. Because of that, an abstract class cannot be instantiated.
overriding/overloading
Overriding
is when a member function is included in aderived class
, havingexactly the same signature
as an inherited member function.A function’s
signature
is defined as:- Function’s name
- Sequence of types in parameter list
- Including order, number, and types of parameters
Signature
doesNOT
include:- Return type
const
keywords used for the function or the parameters- References specifiers (
&
) used for the parameters
Overloading
is whentwo or more functions
with thesame name
are
defined in the same scope, each having different parameter lists.Thus,
overloading
applies to inherited member functions, but also
applies to free functions or operators available within a certain scope.vs. constructor/destructor implementation
assignment operator
copy constructor
shallow/deep copy
11. multiple inheritance (Yes)
12. virtual inheritance (Yes)
13. diamond problem (Yes)
Slide Set 5:
1. statically allocated arrays (one(YES) / multidimensional(NO)
* declaration, usage
* memory allocation model
* passing as parameters
2. dynamically allocated arrays (one-dimensional (YES)) (multidimensional - NO)
* declaration, usage
* memory allocation model
* passing as parameters
3. array decay into a pointer(NO)
4. static array classes (NO)
5. STL containers (NO)
* declaration, usage (NO)
* iterators (NO)
C++ midterm review