程序代写代做代考 compiler c++ CIS 22B – Lecture 2

CIS 22B – Lecture 2

CIS 22C – Recap of Objects
Manish Goel

Classes – Recap
Abstraction & Encapsulation  Data Hiding
Abstraction & Typing  Abstract Data Types
Access Specifiers  private, protected, public
Member functions – accessors, mutators, iterators, overloading
Static members  class “global”
Instantiation – Classes  Objects
Constructors – default, overloading
Destructors – default
Object composition

Classes – Recap (2)
“Friendship” – privileged access
this pointer
Inheritance  Abstraction, Modularity, Hierarchy
Base Class  Derived Class(es)
All base class functionality exists in derived class
Inherited access can be limited
Specialization  Extend class functionality in derived class
Polymorphism  Over-riding  uniqueness, individuality of derived classes  automatically “morph” from one peer form to another peer form

Class Hierarchies
A base class can be derived from another base class.

Redefining Base Class Functions
Redefining function: function in a derived class that has the same name and parameter list as a function in the base class

Typically used to replace a function in base class with different actions in derived class

Not the same as overloading – with overloading, parameter lists must be different

Objects of base class use base class version of function; objects of derived class use derived class version of function

5

Problem with Redefining
Consider this situation:
Class BaseClass defines functions x() and y(). x() calls y().
Class DerivedClass inherits from BaseClass and redefines function y().
An object D of class DerivedClass is created and function x() is called.
When x() is called, which y() is used, the one defined in BaseClass or the the redefined one in DerivedClass?
Object D invokes function X() in BaseClass. Function X() invokes function Y() in BaseClass, not function Y() in DerivedClass, because function calls are bound at compile time. This is static binding.

DerivedClass
void X();
void Y();

void Y();
DerivedClass D;
D.X();

Polymorphism and Virtual Member Functions
Virtual member function: function in base class that expects to be redefined in derived class

Function defined with key word virtual:
virtual void Y() {…}

Supports dynamic binding: functions bound at run time to function that they call
in our prior example, such a signature will result in derived class Y() being called with virtual keyword

At runtime, C++ determined the type of object making the call and bound the function to appropriate version – this type of behavior is known as polymorphism. The term polymorphism means the ability to take many forms.

Without virtual member functions, C++ uses static (compile time) binding

7

Redefinition cannot use Base Class Pointers
#include
using namespace std;

class CPolygon
{
protected:
int width, height;
public:
void setup (int first, int second)
{
width= first;
height= second;
}
};

class CRectangle: public CPolygon
{
public:
int area()
{ return (width * height); }
};

class CTriangle: public CPolygon
{
public:
int area()
{ return (width * height / 2); }
};

int main ()
{
CRectangle rectangle;
CTriangle triangle;

CPolygon* ptr_polygon1 = &rectangle;
CPolygon* ptr_polygon2 = ▵

ptr_polygon1->setup(2,2);
ptr_polygon2->setup(2,2);

cout << rectangle.area() << endl; cout << triangle.area() << endl; return 0; } Courtesy: www.codingunit.com Polymorphism Requires References or Pointers Polymorphic behavior is only possible when an object is referenced by a reference variable or a pointer. Can define a pointer to a base class object and assign it the address of a derived class object Static binding - Base class pointers and references only know about members of the base class, so you can’t use a base class pointer to call a derived class function Dynamic binding - Redefined functions in derived class are called with base class pointer because base class declares the function virtual – this is “over-riding” So a virtual function is dynamically bound and over-ridden and non-virtual function is statically bound and redefined Polymorphism with Base Class Pointers #include
using namespace std;

class CPolygon {
protected:
int width, height;
public:
void setup (int first, int second) {
width= first;
height= second;
}

virtual int area()
{ return (0) };
};

class CRectangle: public CPolygon {
public:
int area()
{ return (width * height); }
};

class CTriangle: public CPolygon {
public:
int area()
{ return (width * height / 2); }
};

int main ()
{
CRectangle rectangle;
CTriangle triangle;
CPolygon polygon;

CPolygon* ptr_polygon1 = &rectangle;
CPolygon* ptr_polygon2 = ▵
CPolygon* ptr_polygon3 = &polygon;

ptr_polygon1->setup(2,3);
ptr_polygon2->setup(2,2);
ptr_polygon3->setup(2,2);

cout << ptr_polygon1->area() << endl; cout << ptr_polygon2->area() << endl; cout << ptr_polygon3->area() << endl; return 0; } Courtesy: www.codingunit.com Virtual Destructors It's a good idea to make destructors virtual if the class could ever become a base class. Otherwise, the compiler will perform static binding on the destructor if the class ever is derived from. Destructor – Static Binding Destructor – Dynamic Binding class Base { public: ~Base() {cout << “Delete Parent\n”;} }; class Derived : public Base { public: ~Derived() {cout << “Delete Child\n;} int main() { Base *b = new Derived; delete b; } class Base { public: virtual ~Base() {cout << “Delete Parent\n”;} }; class Derived : public Base { public: ~Derived() {cout << “Delete Child\n;} int main() { Base *b = new Derived; delete b; } Abstract Base Classes and Pure Virtual Functions Pure virtual function: a virtual member function that must be overridden in a derived class that has objects Abstract base class contains at least one pure virtual function: virtual void Y() = 0; The “= 0” indicates a pure virtual function Must have no function definition in the base class Abstract base class: class that cannot be instantiated, i.e. can have no objects. Serves as a basis for derived classes that may/will have objects. A class becomes an abstract base class when one or more of its member functions is a pure virtual function 12 Polymorphism – Abstract Base Classes #include
using namespace std;

class CPolygon
{
protected:
int width, height;

public:
void setup (int first, int second)
{
width= first;
height= second;
}

virtual int area() = 0;
};

class CRectangle: public CPolygon
{
public:
int area(void)
{ return (width * height); }
};

class CTriangle: public CPolygon
{
public:
int area(void)
{ return (width * height / 2); }
}
};

int main ()
{
CRectangle rectangle;
CTriangle triangle;

CPolygon* ptr_polygon1 = &rectangle;
CPolygon* ptr_polygon2 = ▵

ptr_polygon1->setup(2,2);
ptr_polygon2->setup(2,2);

cout << ptr_polygon1->area() << endl; cout << ptr_polygon2->area() << endl; return 0; } Courtesy: www.codingunit.com Abstract Base Classes with Dynamic Allocation #include
using namespace std;

class CPolygon
{
protected:
int width, height;

public:
void setup (int first, int second)
{
width= first;
height= second;
}

virtual int area(void) = 0;

void onscreen(void)
{ cout << this->area() << endl; } }; class CRectangle: public CPolygon { public: int area(void) { return (width * height); } }; class CTriangle: public CPolygon { public: int area(void) { return (width * height / 2); } }; int main () { CPolygon *ptr_polygon1 = new CRectangle; CPolygon *ptr_polygon2 = new CTriangle; ptr_polygon1->setup(2,2);
ptr_polygon2->setup(2,2);

ptr_polygon1->onscreen();
ptr_polygon2->onscreen();

delete ptr_polygon1;
delete ptr_polygon2;

return 0;
}

Courtesy: www.codingunit.com

Inheritance Models

Courtesy: www.codingunit.com

Multiple Inheritance
A derived class can have more than one base class
Each base class can have its own access specification in derived class’s definition:
class Teacher: public Person, public Employee;

Arguments can be passed to both base classes’ constructors:
Teacher(string strName, int nAge, bool bIsMale, string strEmployer, double dWage, int nTeachesGrade)
: Person(strName, nAge, bIsMale), Employee(strEmployer, dWage),
m_nTeachesGrade(nTeachesGrade

Base class constructors are called in order given in class declaration, not in order used in class constructor

class
Person
class
Employee
class
Teacher

16

#include
#include
using namespace std;

class Person
{
private:
    string m_strName;
    int m_nAge;
    bool m_bIsMale;
 
public:
    Person(string strName, int nAge,
bool bIsMale) : m_strName(strName),
m_nAge(nAge), m_bIsMale(bIsMale) { }
 
    string GetName() { return m_strName; }
    int GetAge() { return m_nAge; }
    bool IsMale() { return m_bIsMale; }
};
 
class Employee
{
private:
    string m_strEmployer;
    double m_dWage;
 
public:
    Employee(string strEmployer, double
dWage) : m_strEmployer(strEmployer),
m_dWage(dWage) { }
 
    string GetEmployer()
{ return m_strEmployer; }
    double GetWage() { return m_dWage; }
};
// Teacher publicly inherits Person and Employee
class Teacher: public Person, public Employee
{
private:
     int m_nTeachesGrade;
 
public:
    Teacher(string strName, int nAge,
bool bIsMale, string strEmployer,
double dWage, int nTeachesGrade)
      : Person(strName, nAge, bIsMale),
Employee(strEmployer, dWage),
m_nTeachesGrade(nTeachesGrade) { }
};

int main()
{
Teacher T(“MG”, 47, 1, “DeAnza”, 500, 5);

cout << "Teacher's Name: " << T.GetName() << endl; cout << "Teacher's Age: " << T.GetAge() << endl; cout << "Teacher's Employer: " << T.GetEmployer() << endl; cout << "Teacher's Salary: " << T.GetWage() << endl; return 0; } Courtesy: www.learncpp.com Multiple Inheritance Problem: what if base classes have member variables/ functions with the same name? Solutions: Derived class redefines the multiply-defined function Derived class invokes member function in a particular base class using scope resolution operator :: Compiler errors occur if derived class uses base class function without one of these solutions Programmers try to avoid multiple inheritance to keep modeling simple #include
using namespace std;

class Monitor
{
private:
long m_lID;

public:
Monitor (long lID) : m_lID(lID) { }
long GetID() { return m_lID; }
};

class CPU
{
private:
long m_lID;

public:
CPU (long lID) : m_lID(lID) { }
long GetID() { return m_lID; }
};

class LabComputer: public Monitor, public CPU
{
public:
LabComputer (long lUSBID, long lNetworkID)
: Monitor (lUSBID), CPU (lNetworkID) { }
};

int main()
{
LabComputer c54G(5442, 181742);
cout << c54G.GetID(); // Which GetID() return 0; } #include
using namespace std;

class Monitor
{
private:
long m_lID;

public:
Monitor (long lID) : m_lID(lID) { }
long GetID() { return m_lID; }
};

class CPU
{
private:
long m_lID;

public:
CPU (long lID) : m_lID(lID) { }
long GetID() { return m_lID; }
};

class LabComputer: public Monitor, public CPU
{
public:
LabComputer (long lUSBID, long lNetworkID)
: Monitor (lUSBID), CPU (lNetworkID) { }
};

int main()
{
LabComputer c54G(5442, 181742);
cout << c54G.CPU::GetID(); // Correct Way return 0; } Courtesy: www.learncpp.com The this Pointer this: predefined pointer available to a class’s member functions Always points to the instance (object) of the class whose function is being called Is passed as a hidden argument to all non-static member functions Can be used to access members that may be hidden by parameters with same name class SomeClass { private: int num; public: void setNum(int num) { this->num = num; }

};

20

Operator Overloading
Operators such as =, +, and others can be redefined when used with objects of a class
The name of the function for the overloaded operator is operator followed by the operator symbol, e.g.,
operator+ to overload the + operator, and
operator= to overload the = operator
Prototype for the overloaded operator goes in the declaration of the class that is overloading it
Overloaded operator function definition goes with other member functions
Prototype: void operator=(const SomeClass &rval)

return
type

function
name

parameter for
object on right
side of operator

21

Operator Overloading – things to consider
At least one operand for an overloaded operator must be a user defined type
Only existing operators can be overloaded
e.g. “**” cannot be defined to calculate exponent
Operator overloading cannot change operator precedence and associativity
i.e. an exponent operator will be calculated before addition
When evaluating an expression with operators:
If operands are built-in types, C++ calls built-in routines
If any operand is UDT, C++ checks for overloaded operator function
Otherwise results in compiler error

Invoking an Overloaded Operator
Operator is called via object on left side
Operator can be invoked as a member function:
object1.operator=(object2);
It can also be used in more conventional manner:
object1 = object2;
Return type the same as the left operand
Supports notation like:
object1 = object2 = object3;
Function declared as follows:
const SomeClass operator=(const someClass &rval)
In function, include as last statement:
return *this;

23

Returning a Value
Overloaded operator can return a value
class Point2d
{
public:
double operator-(const point2d &right)
{ return sqrt(pow((x-right.x),2)
+ pow((y-right.y),2)); }

private:
int x, y;
};

Point2d point1(2,2), point2(4,4);

// Compute and display distance between 2 points.
cout << point2 – point1 << endl; // displays 2.82843 24 More on Overloaded Operators Can change meaning of an operator Cannot change the number of operands of the operator Most mathematical operators can be overloaded. ++, -- operators overloaded differently for prefix vs. postfix notation Overloaded relational operators should return a bool value Overloaded stream operators >>, << must return reference to istream, ostream objects and take istream, ostream objects as parameters Cannot overload the following operators: ?: . .* :: sizeof 25 Overloaded [] Operator Can create classes that behave like arrays e.g. string class  char array Elements of string accessed similar to elements of char array because the char array is a member of the string string sName = “William”; cout << sName[0]; // prints ‘W’ (char) // similar to sName.m_char[0] = ‘W’ Overloaded [] provide bounds-checking on subscripts Must consider constructor, destructor for array allocation / destruction Overloaded [] returns a reference to object, not an object itself, i.e. sName[0] <> sName

26

Cannot Access Private Member Array Write Setter’s and Getter’s for manipulating private member array Overload [ ] to make class behave like array
class IntList
{
private:
    int m_anList[10];
};
 
int main()
{
    IntList cMyList;
    return 0;
}
class IntList
{
private:
    int m_anList[10];
 
public:
    void SetItem(int nIndex, int nData)
{ m_anList[nIndex] = nData; }
    int GetItem(int nIndex)
{ return m_anList[nIndex]; }
};

int main()
{
    IntList cMyList;
    cMyList.SetItem(2, 3);
 
    return 0;
}
class IntList
{
private:
    int m_anList[10];
 
public:
    int& operator[] (const int nIndex);
};
 
int& IntList::operator[] (const int nIndex)
{
    return m_anList[nIndex];
}

int main()
{
IntList cMyList;
cMyList[2] = 3; // set a value
cout << cMyList[2]; // get a value       return 0; } Object Conversion Type of an object can be converted to another type Automatically done for built-in data types Must write an operator function to perform conversion To convert an FeetInches object to an int or double: FeetInches::operator int() {return feet;} FeetInches::operator double() { double temp = feet; temp += (inches / 12.0); return temp; } Assuming distance is a FeetInches object, allows statements like: int i = distance; double d = distance; 28 Exceptions Indicate that something unexpected has occurred or been detected Allow program to deal with the problem in a controlled manner Can be as simple or complex as program design requires Exception: object or value that signals an error Throw an exception: send a signal that an error has occurred Catch/Handle an exception: process the exception; interpret the signal Exceptions – How they work throw – followed by an argument, is used to throw an exception try – followed by a block { }, is used to invoke code that throws an exception catch – followed by a block { }, is used to detect and process exceptions thrown in preceding try block. Takes a parameter that matches the type thrown. A function that throws an exception is called from within a try block If the function throws an exception, the function terminates and the try block is immediately exited. A catch block to process the exception is searched for in the source code immediately following the try block. If a catch block is found that matches the exception thrown, it is executed. If no catch block that matches the exception is found, the program terminates. Exceptions – Example // function that throws an exception int totalDays(int days, int weeks) { if ((days < 0) || (days > 7))
throw “invalid number of days”;
// the argument to throw is the character string
else
return (7 * weeks + days);
}

// in the caller or main
try // block that calls function
{
totDays = totalDays(days, weeks);
cout << "Total days: " << days; } catch (char *msg) //interpret exception from char string passed { cout << "Error: " << msg; } From Program 16-1 From Program 16-1 What Happens in theTry/Catch Construct What if no exception is thrown? Exceptions - Notes Predefined functions such as new may throw exceptions Value thrown does not need to be used in catch block. so, no name is needed in catch parameter definition catch block parameter definition does need the type of exception being caught An exception will not be caught if it is thrown from outside of a try block there is no catch block that matches the data type of the thrown exception If an exception is not caught, the program will terminate Exceptions – Notes (2) Once an exception is thrown, the program cannot return to throw point. The function executing throw terminates (does not return), other calling functions in try block terminate, resulting in unwinding the stack If objects were created in the try block and an exception is thrown, they are destroyed. Nested try blocks – try/catch blocks can occur within an enclosing try block. Exceptions caught at an inner level can be passed up to a catch block at an outer level: catch ( ) { ... throw; // pass exception up } // to next level Exceptions and Objects An exception class can be defined in a class and thrown as an exception by a member function An exception class may have: no members: used only to signal an error members: pass error data to catch block A class can have more than one exception class 38 Contents of Rectangle.h (Version1) (Continued) Program 16-2 (Continued) Function Templates Function template: a pattern for a function that can work with many data types When written, parameters are left for the data types When called, compiler generates code for specific data types in function call 45 Function Template Example template
T times10(T num)
{
return 10 * num;
}
template
prefix

generic
data type

type
parameter

What gets generated when times10 is called with an int: What gets generated when times10 is called with a double:
int times10(int num)
{
return 10 * num;
} double times10(double num)
{
return 10 * num;
}

46

Function Template Example
template
T times10(T num)
{
return 10 * num;
}
Call a template function in the usual manner:
int ival = 3;
double dval = 2.55;
cout << times10(ival); // displays 30 cout << times10(dval); // displays 25.5 47 Function Template Notes Can define a template to use multiple data types: template
Example:
template // T1 and T2 will be
double mpg(T1 miles, T2 gallons) // replaced in the
{ // called function
return miles / gallons // with the data
} // types of the
// arguments

48

Function Template Notes
Function templates can be overloaded Each template must have a unique parameter list
template
T sumAll(T num) …
template
T1 sumall(T1 num1, T2 num2) …

49

Function Template Notes
All data types specified in template prefix must be used in template definition
Function calls must pass parameters for all data types specified in the template prefix
Like regular functions, function templates must be defined before being called

50

Function Template Notes
A function template is a pattern
No actual code is generated until the function named in the template is called
A function template uses no memory
When passing a class object to a function template, ensure that all operators in the template are defined or overloaded in the class definition

51

Where to Start
When Defining Templates
Templates are often appropriate for multiple functions that perform the same task with different parameter data types
Develop function using usual data types first, then convert to a template:
add template prefix
convert data type names in the function to a type parameter (i.e., a T type) in the template

Class Templates
Classes can also be represented by templates. When a class object is created, type information is supplied to define the type of data members of the class.
Unlike functions, classes are instantiated by supplying the type name (int, double, string, etc.) at object definition

53

Class Template Example
template
class grade
{
private:
T score;
public:
grade(T);
void setGrade(T);
T getGrade()
};

Class Template Example
Pass type information to class template when defining objects:
grade testList[20];
grade quizList[20];
Use as ordinary objects once defined

Class Templates and Inheritance
Class templates can inherit from other class templates:
template
class Rectangle
{ … };
template
class Square : public Rectangle
{ … };
Must use type parameter T everywhere base class name is used in derived class

56

/docProps/thumbnail.jpeg