Professional Documents
Culture Documents
Week 1: Getting Started With C++: Background
Week 1: Getting Started With C++: Background
Overview
Background
C++ joins two separate programming traditions (procedural language and object-oriented
programming language) - It will be fun to learn.
Unix
C++ Builder
From C to C++
Object-Oriented Programming
The OOP approach to program design is to first design classes that accurately represent those
things with which the program deals
ANSI C
Microsoft C++
IBM Visual Age C++
Borland C++
Java
Startup Code
Library Code
C++ Initiation
// General Format
int main(void) // Vs void main(void), int main(), etc
{
statements
return 0;
}
Comments
// All the text behind this line will be commented
/*
* ANSC C Style Comment
* All the text between will be commented
*/
/*
* /* What about this ? */
*
*/
/*
* // How about this
*
*/
// Be careful on some platform, how long of a line it will take in general
It is a program that processes a source file before the main compilation take place.
#include <iostream.h> caues the preprocessor to add the contents of iostream.h file to your
program
(Adding or replacing text is very common)
Source-Code Formatting
/*
* What about the following
*/
#include <iostream.h> // Preprocessor directive
int
main(void){
cout
<< "The Classic Hello World" << endl;
return 0;}
cin
cin >> myInput;
cout << "Input is " << myInput << "of Value" << endl;
Functions
Declaration with prototyping
report (25);
week1.cpp
week1.out
Loops and Branches are quite similar to C, Java, Fortarn, Basic, etc
Loop
In C++, we have
for loop
while loop
do while loop
for Loop Part I
Syntax:
Example:
There are two version (prefix version ++x, postfix version x++)
Example:
cout << "a = " << a << ": b = " << b << "\n";
cout << "a++ = " << a++ << ": ++b = " << ++b << "\n";
cout << "a = " << a << ": b = " << b << "\n";
return 0;
}
// The output will be
// a = 20: b = 20
// a++ = 20: ++b = 21
// a = 21: b = 21
More Example:
int x = 5;
int y = ++x; // change x, then assign to y
// y is 6, x is 6
int z = 5;
int y = z++; // assign to y, then change z
// y is 5, z is 6
i = i + y; // Can be rewritten as
i += y;
Example:
int k = 5;
k += 3; // Now, k is set to 8
Block Statement
It is kind of a trick
Relational Expression
Example:
Note:
myint = 4; // Assignment
myint == 4 // Logical cmparsion
while Loop
A for loop stripped off the initialization and update parts. It is more general for application
programmers
Syntax:
while (test-condition)
body
Example:
for vs while
Do while Loop
Syntax:
do
body
while (test-expression);
Example:
// dowhile.cpp -- exit-condition loop
#include <iostream.h>
int main(void)
{
int n;
maxReplacements is 5 !
while (inputFile.good())
{
....
}
// OR
while (cin.get(ch)) // cin.get(ch) is 0 on EOF
{
cout << ch;
count ++;
}
Branching Statements and Logical Operators
Syntax:
if (test-condition)
statement1
else
statement2
Example:
// Example 1
if (ch == 'A')
a_grade++;
else
if (ch == 'B')
b_grade++;
else
soso++;
// Example 2
if (ch == 'A')
a_grade++;
else if (ch == 'B')
b_grade++;
else
soso++;
Logical Expression
OR: ||
// It is the same as
if (x <= 5)
{
// do something
}
// Range test
if ((x > 5) && (x < 10))
{
// We are in the right range
// do something
}
Switch Statement
week2a.out
week2b.cpp
week2b.in
week2b.out
Example:
int transactionCount;
transactionCount = 5;
Name
Only alphabetic characters, digits and _ are allowed
No length limit
Example:
int sum;
int sum_of_records;
int sumOfRecords;
Unsigned Type
Example:
#include <iostream.h>
int main(void)
{
char c = 'M'; // assign ASCII code for M to c
int i = c; // store same code in an int
cout << "The ASCII code for " << c << " is " << i << "\n";
const int Months = 12; // value set once, cannot be changed later, works like a constant
Floating-Point Numbers
Example:
float a = 2.34E+22;
Arrays
A data from that can hold several values of all of one type
Example:
String
A string is a series of characters stored in consecutive bytes of memory. All string ends with \0
More on String
#include <iostream.h>
int main(void)
{
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
Example:
int main(void)
{
inflatable guest =
{
"Glorious Gloria", // name value
1.88, // volume value
29.99 // price value
}; // guest is a structure variable of type inflatable
// It's initialized to the indicated values
inflatable pal =
{
"Audacious Arthur",
3.12,
32.99
}; // pal is a second variable of type inflatable
// NOTE: some implementations require using
// static inflatable guest =
cout << "Expand your guest list with " << guest.name;
cout << " and " << pal.name << "!\n";
// pal.name is the name member of the pal variable
cout << "You can have both for $";
cout << guest.price + pal.price << "!\n";
return 0;
}
week3a.cpp
week3a.out
week3b.cpp
week3b.in
week3b.out
Function Review
In C++, in order to use a function, it is kind of like using a variable, you must
Example:
int main(void)
{
cout << "main() will call the simple() function:\n";
simple(); // function call
return 0;
}
// function definition
void simple(void)
{
cout << "I'm just a simple country function.\n";
}
Define a function
Syntax:
typename functionName(argumentlist)
{
statements
return value; // value is of type typename, can be void
}
Example:
Example:
void cheers(int n)
{
for (int i = 0; i < n; i++)
cout << "Cheers! ";
cout << "\n";
}
double cube(double x)
{
return x * x * x;
}
Numerical value of the argument is passed to the function, where it is assigned to a new variable
(e.g. double volume = cube(side);)
double cube(double x)
{
return x * x * x;
}
When the function is called, the system creates variable called x and assigns it passed value of 5.
So, the value is copied. (passed by value)
Thus, eash function has its own variables with their own values
Multiple Arguments
Example:
Pass By Reference
So, change of the input value is not possible (since changing the copy is different than changing
the original input value)
int main(void)
{
int myInt = 5;
cout << "The original value of myInt is " << myInt << endl;
testProc(&myInt);
cout << "Now, after calling the procedure, the value of myInt is " <<
myInt << endl;
return 0;
}
void testProc(int * x)
{
// Change the value of the input parameter
*x = 99;
return;
}
// The output will be:
The original value of myInt is 5
Now, after calling the procedure, the value of myInt is 99
Once you have a const keyword, then, whatever variable (pointer or not) associated with it
cannot be changed
An array of char
Example:
char hi[15] = "Richard";
char * str = "Richard";
int n1 = strlen(hi); // hi is &hi[0]
int n2 = strlen(str); // pointer to char
int n3 = strlen("Richard"); // address of string
New addition to C
Polymorphism means having many forms, so function polymorphism lets a function to have
many forms
Example:
week4a.out (output)
week4b.out (output)
Pointers Review
The address of char looks the same as the address a double (both are just hex number)
For example:
int * p_updates;
* operator is used by applying it to a pointer, the p_updates variable itself must be a pointer
*p_update is an int
int higgens;
int *pi = &higgens;
Memory actually get allocated when the "int higgen" statement is executed
If we want to init pointer from ground up, we have to use the new operator:
week4fr.hpp
week4fr.cpp
week4a.cpp
week4a.out
week4b.cpp
week4b.out
The name of this class is OOP using C++
Think about the data needed to describe the object and about the operations that will describe the
user's interaction with the data
Class is the second OO concept we have, the first one is function overloading.
In computing, abstraction is the crucial abstract the essential operational features of a problem
and express a solution in those terms.
The Class
It determines how much memory will be needed for a data object. (Automatic when you declare
it correctly)
It determines what operations, or methods, can be performed using the data object
The class is the C++ vehiclefor translating an abstraction to a user-defined type. It combines data
representation and methods for manipulating that data into one neat package.
Class is like a template for making cookie, and object is like the actually cookie
// stocks.cpp
#include <iostream.h>
#include <stdlib.h> // for exit()
#include <string.h> // for strcpy()
class Stock
{
private:
char company[30];
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
void acquire(const char * co, int n, double pr);
void buy(int num, double price);
void sell(int num, double price);
void update(double price);
void show();
};
void Stock::acquire(const char * co, int n, double pr)
{
strcpy(company, co);
shares = n;
share_val = pr;
set_tot();
}
void Stock::show()
{
cout << "Company: " << company
<< " Shares: " << shares << '\n'
<< " Share Price: $" << share_val
<< " Total Worth: $" << total_val << '\n';
}
int main(void)
{
Stock stock1;
stock1.show();
stock1.buy(15, 18.25);
stock1.show();
return 0;
}
Special method call constructor and destructor should be provided for a class
If not provided, C++ will provide a default constructor and destructor (which just do nothing but
initization or basic clean up)
Constructor is used to construct (create) an object, normally programmer will init all the
necessary variable in the constructor
Example:
// Constructor Example
Stock::Stock()
{
strcpy(company, "no name");
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
// Destructor
Stock::~Stock()
{
cout << "Bye, " << company << endl;
}
// Init an object
Stock stock1();
week5.out (output)
Week 6:
Operator Overloading and Friends Functions
Overview
The same principal follows: "one kind of operator can have many forms"
Operator Overloading
The operator '*'. If it applies to an address, it yields the value stored at that address (de-reference)
// Instead of using
for (int i = 0; i < 20; i++)
evening[i] = carmen[i] + richard[i]; // Add element by element
Syntax
operatorop(argument-list)
Where op is the symbol for the operator being overloaded, op must be a valid operator in C++
E.g
If richard, carmen, couple are objects of Peoples class, then we can write
Or recognizing the operands as belonging to the Peoples class, we can rewrite it to:
couple = richard.operator+(carmen);
land.show(); // This will fail, because show does not guarantee that
// it won't modify the invoking object. And show has no
// parameter, so there is no trick we can play in the
parameter list
So, C++ allows that we use the const keyword after the function declaration
Example:
A Vector Class
Our first example: A vector, used in engineering and physic a lot, is a quantity having both a
magnitude (size) and a direction
Example:
C++ controls access to the private portions of a class object (by the use of private and public
sessions)
Might be too rigid to fit particular programming problems ... So we have 'friends'
Friend functions
Friend classes
Friend member functions
By making a function a friend to a class, you allow the function the same access privileges that a
member function of the class has
Often overloading a binary operator (a operator with two arguments) for a class generates a need
for friends
For example:
// Or in alternative form
Vector v1 = myvect.operator*(2.0);
The above function require that operator*() be a member function of the Vector class AND the
function takes a type double arugment
operator*(2.0, myvector);
A friend function is a nonmember function that is allowed access to an object's private section
Example:
In General, if you want to overload an operator for a class and you want to use the operator with
a nonclass term as the first operand, you have to use a friend function to reverse the operand
order.
Both Friend and Operator Overloading are "Good and Bad" features in C++
Operator Overloading makes the object operations much compact and relatively easier to code
However, once operators are overloaded, code maintance becomes more expensive. For
example, + now can be applied to multiple different objects and all the implementation is internal
... it might be a nightmare for someone to change or update the existing code.
Friend, on the other hand, breaks the donut concept we have. Data encapsulation can be broken
by friend functions.
However, friend will be your good friend when you are doing performance enhancement or
quick bug fix.
week6.out (output)
New subclasses can be derived from an existing class through the use of inheritance
Inheritance allows programmers to create new subclasses that reuse the code and data in the base
class without having to repeat them
Yet these new subclasses are customized to meet the specific needs of the application
Polymorphism is the ability of subclasses of the same class to respond to the same input message
and produce different results
Polymorphism combines the concepts of inheritance and dynamic binding (realtime binding)
HAS-A relationship is the same as "contain" relationship - For example, the Bank object
contains People object, Account object, Report object, etc. Or, Lunch has a Banana.
USE-A relationship means an object uses another object's methods. A common way of
description is that an object sends a message to another object through the public method. For
example, cleint sending server a message for processing.
IS-A relationship is Inheritance. It can be described as the parent-child relationship.A child get
all the stuffs inherits from the parent. Some people describe that as super class-sub class OR base
class - derived class. Or, Banana is a Fruit.
IS-A relationship is the bases for software reuse (if design, implement and use correctly)
Syntax - Protected and Private
Up to this point, in our class definition, we only have private and public
The protected keyword is like private that in the outside world can access class members in a
protected section only by using the class members methods.
Keyword private and protected's difference comes into play only within classes derived from the
base class
Members of a derived class can access protected members of a base class directly, BUT they
cannot directly access private members of the base class
In short: Protected class members are private to the world at large, but public to a derived class
// Syntax example
// More later at the demo
class ArrayDb
{
private:
unsigned int size; // number of array elements
protected:
double * arr; // address of first element
public:
ArrayDb(); // default constructor
// create an ArrayDb of n elements, set each to val
ArrayDb(unsigned int n, double val = 0.0);
// create an ArrayDb of n elements, initialize to array pn
ArrayDb(const double * pn, unsigned int n);
ArrayDb(const ArrayDb & a); // copy constructor
~ArrayDb(); // destructor
unsigned int arsize() const {return size;} // returns array size
// overloaded operators
double & operator[](int i); // array indexing
const double & operator[](int i) const; // array indexing (no =)
ArrayDb & operator=(const ArrayDb & a);
friend ostream & operator<<(ostream & os, const ArrayDb & a);
};
#endif
C++ actually supports three types of inheritance - public, protected and private
It can be throught as a short hand for saying that an object of a derived class should also be an
object of the base class
Anything you do with a base object, you should be able to do with a derived object
For example, we can derive a Banana class from the Fruit class. The new class would inherit all
the data members of the original class, so a Banana object would have members representing the,
say weight and caloric content of a banana. But Banana can have Banana specific info, such as
"Peel color"
In general, inheritance can add properties to a base class; it does not remove properties from a
base class
Other Inheritance
Public Inheritance is the most common form of inheritance. However, sometime we might need
protected and private inheritance as well. Their main differences are the access authority of data.
Here is a quick look:
Property Public Inheritance Protected Private Inheritance
public members public members of the protected members of private member of the
become derived class the derived class derived class
protected
protected members of the protected members of private members of the
members
derived class the derived class derived class
become
private
accessible only through the accessible only through accessible only through the
members
base class interface the base class interface base class interface
become
Syntax rule by C++: When creating an object of a derived class, a program first calls the base
class constructor, then the derived class constructor. When an object of a derived class expires,
the program first calls the derived class destructor, if any, then the base class destructor.
// Example:
#include "arraydb.h"
// new methods
double sum() const;
double average() const;
// overloaded operators
ArithArr operator+(const ArithArr & a) const;
ArithArr operator-(const ArithArr & a) const;
ArithArr operator-() const;
ArithArr operator*(const ArithArr & a) const;
ArithArr operator*(double d) const;
friend ArithArr operator*(double d, const ArithArr & a);
};
#endif
If your proposed derived class is not a particular kind of the base class, do not use public
derivation. For example, do not derive a Computer class from a Programmer class ... you might
make a Computer class object a member of the Programmer class
A base class pointer can point to a derived class object and that a base class reference can refer to
a derived class object without an explicit type cast. But the reverse is not true (more on next
week) ... you can not have a derived class pointer or reference refer to a base class object without
explicit type cast. Depending upon the class declarations, such an explicit type cast (a downcast)
may or may not make sense
When object is destroyed, the program first calls the derived destructor, then the base destructor
If you overload the assignment operator '=', it will not be inherited. The system will not allow
doing so. Otherwise, it will be a big mess
Only use Inheritance when needed. Some people said OOD is an art and can be perfected by
practice (read try, then success or fail ...) A good example is the MSVC++ version 1.0 ... almost
every component is inherited.
Lab
Employee.hpp (class definition)
week7.out (output)
Overview
We could say that Inheritance is the most important feature in C++
Remember that a "rule" states that a reference or pointer to a derived class object is converted to
a reference or pointer to a base class object when used as an argument to a function defined as
accepting a reference or a pointer to a base class object
Also, a base class pointer can point to a derived class object and that a base class reference can
refer to a derived class object without an explicit type cast. But the reverse is not true, you can
not have a derived class pointer or reference refer to a base class object without explicit type
cast. Depending upon the class declarations, such an explicit type cast (a downcast) may or may
not make sense
Today, we will talk about the "tool" that enhances the features of inheritance in C++ - Virtual
function
When a compiler compiles the source code file containing the function definition, it has no way
of knowing what type of object will be passed to it as an argument in some other file.
The only choice the compiler can make at compile time is to match class methods to the type of
reference or pointer.
The term binding refers to attaching a function call to a particular function definition
In C, you have only one function per name, so the choice is obvious for the compiler
In C++, with function overloading and redefined member functions, we can have more than once
function matching a given name
It passes responsibility to the program, which then makes a runtime decision whenever it actually
executes a method function call (We will use the lab as example ...)
Dynamic Binding
Then, redefine the function in a derived class, a program then will use dynamic binding to
determine which definition to use
Once it is a virtual method, if remains virtual for all classes derived from the base class
Thus, for a given method, you only have to use the keyword virtual once, in the base class
In a nutshell, virtual member functions are created by preceding the prototype with the keyword
virtual. C++ programs then use dynamic, or late, binding for virtual methods, and static, or early,
binding for nonvirtual methods.
Also, for virtual functions, the type of object referred to or pointed to determines which method
to a pointer or reference invokes
class ArrayDb
{
private:
unsigned int size; // number of array elements
protected:
double * arr; // address of first element
public:
ArrayDb(); // default constructor
// create an ArrayDb of n elements, set each to val
ArrayDb(unsigned int n, double val = 0.0);
// create an ArrayDb of n elements, initialize to array pn
ArrayDb(const double * pn, unsigned int n);
ArrayDb(const ArrayDb & a); // copy constructor
virtual ~ArrayDb(); // destructor
unsigned int arsize() const {return size;}// returns array size
// overloaded operators -- note use of keyword virtual
virtual double & operator[](int i); // array indexing
virtual const double & operator[](int i) const; // array indexing (no
=)
ArrayDb & operator=(const ArrayDb & a);
friend ostream & operator<<(ostream & os, const ArrayDb & a);
};
#endif
Notes on Binding
Efficiency, for making dynamic binding decision, program has to keep track of what sort of
object a base class pointer or reference refers to, and that entails some extra processing overhead
Second, without making a function virtual, that means we announce that it is our intention that
this function not be redefined. Thus, we have control over our class design
In short, if a method in a base class will be redefined in a derived class, make it virtual. If the
method should not be redefined, make it nonvirtual
// Syntax Example
class Employee
{
public:
virtual void showme(int a) const;
...
}
class Programmer : public Employee
{
public:
void showme(int a) const;
...
}
C++ has a variation of the virtual function call a "pure virtual function"
class Shape
{
public:
virtual void draw() const = 0;
virtual double area() const - 0;
...
}
When a class declaration contains a pure virtual function, you cannot create an object of that
class. So, the idea of pure virtual function only exist in base class
The base class of the pure virtual function then is called abstract base class (ABC)
For example, Shape will be a good candiate for ABC, since there is actually no "Shape" in the
real world. There might be Triangle, Rectangle or Circle ... but not Shape
As a matter of fact, ABC can be used to describes an interface in terms of pure virtual functions,
can a class derived from an ABC uses regular virtual functions to implement the interface in
terms of the properties of the particular derived class
Inline Functions
This is a programming short cut in a sense (this topic is included for completion, it is not directly
related to inheritance, however, quite a few people use this technique for quick virtual member
function)
Use does not need to change the way he/she codes, C++ compiler will incorporate them (inline
functions) into a program
When normal function is called, processor will usually save all the register information, memory
information, then jump to the location of the function (at that point, it will be some session of
machine code)
When the normal function finish execution, it will then restore all the registers and memory
information, then jump back to the point in the program after the function execution
With C++ inline function, C++ compiler compiles the function "in line" with the other code in
the program
The compiler replaces the function call with the corresponding function code in the machine
language level, so no jump of function call is necessary
BUT, there is a memory penalty. If a program calls an inline function ten times, then the program
winds up with ten copies of the function inserted into the code
Syntax Note
Place the function definition above all the functions that call it
Note that you have to place the entire definition (meaning the function header and all the
function code), not just the prototype, above the other functions
The compiler does not have to honor your request to make a function inline. It may decide the
function is too large or notice that it calls itself (recursion is not allowed for inline functions), or
the feature may not be implemented for your particular compiler
Example:
int main(void)
{
double a, b;
double c = 13.0;
a = square(5.0);
b = square(4.5 + 7.5); // can pass expressions
cout << "a = " << a << ", b = " << b << "\n";
cout << "c = " << c;
cout << ", c squared = " << square(c++) << "\n";
cout << "Now c = " << c << "\n";
return 0;
}
Lab
week8.out (output)
Overview
Inheritance and containment are good, but they aren't always the answer to a desire to reuse code.
For example, we defined a function that swapped two int values. Something likes:
void swap(int &a, int &b);
If we want to swap two double value instead of int, then, one approach is to duplicate the original
code, but replace each int with double
Now, if we need to swap two chars, then, we have to duplicate again. At the end of the day, we
have three set of similar code to maintain and change ...
C++'s function template capability automates the process, saving you time and providing greater
reliability
// Format example
template <class Any> // Set up template, and name it arbitray type Any
// FYI - A lot of people like just a name T
void swap(Any &a, Any &b) // Swap logic
{
Any temp;
temp = a;
a = b;
b = temp;
};
If we want a function to swap int, then the compiler will create a function following the template
pattern, substituting int for Any. Similarly, if you need a function to swap doubles, the compiler
will follow the template, substituting the double type for Any
Use templates if you need functions that apply the same algorithm to a variety of types
Many C++ compilers do not yet support templates at the time of this writing. Also, until the final
version of the ANSI/ISO C++ standard comes out (when ?), template details are subject to
change.
// Example:
// funtemp.cpp -- using a function template
#include <iostream.h>
// function template prototype
template <class Any>
void swap(Any &a, Any &b);
int main(void)
{
int i = 10, j = 20;
cout << "i, j = " << i << ", " << j << ".\n";
cout << "Using compiler-generated int swapper:\n";
swap(i,j); // generates void swap(int &, int &)
cout << "Now i, j = " << i << ", " << j << ".\n";
return 0;
}
If you want to use the same kind of function to do the function call, instead of using a compiler
generated template function. Then, a specification will be useful
The original template facility called for the compiler to use the nontemplate version, treating it as
a specialization of the template
Note that the <int> appears in the prototype, not in the function call. It also should appear in the
function definition
Class Templates
The concept of function templates can be pushed one level higher to become class templates
Suppose we have an ArrayDB class that will store integers and have methods to deal with them
... now, it will be nice if we could use the same code to store double, float or char or string
C++'s class templates provide a good way to generate generic class declarations
Templates provide parameterized types, that is, the capability of passing a type name as an
argument to an algorithm for building a class or a function. By feeding the type name int to a
ArrayDB template, for example, you can get the compiler to construct a ArrayDB class for
dealing with ints
The following example shows the combined class and member function templates
It is important to realize that these are not class and member function definitions, they are
instructions to the C++ compiler about how to generate class and member functions
A particular actualization of a template, such as a stack class for handling String objects, is called
an instantiation
If you separate the template member functions in a separate implementation file, most compilers
will not compile
The simplest way to make this work is to place all the template information in a header file and
to include the header file in the file that will use the templates
Example:
// stacktp.h
#include "booly.h"
Lab
week9.out (output)
Overview
We are going to have a "soft" lecture in OOD and OOP this week
We are going to survey a general method in OOD called CRC cards and look at the most popular
tool in OO Engineering called Rational Rose
CRC Cards