162
C++ Programming Languages Lecturer: Omid Omid Jafarinezhad Jafarinezhad Fall 2013 Lecture 4: Object Oriented Programming Department of Computer Engineering Department of Computer Engineering 1

C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

  • Upload
    others

  • View
    14

  • Download
    0

Embed Size (px)

Citation preview

Page 1: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

C++ Programming Languages

Lecturer: OmidOmid JafarinezhadJafarinezhad

Fall 2013

Lecture 4: Object Oriented Programming

Department of Computer EngineeringDepartment of Computer Engineering 1

Page 2: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Outline

•• objectobject--oriented programmingoriented programming –– Classes and class membersClasses and class members

–– Access functions and encapsulationAccess functions and encapsulation

–– Constructors and Destructors Constructors and Destructors

–– Class code and header filesClass code and header files

–– Operator overloadingOperator overloading

–– CompositionComposition

–– InheritanceInheritance

–– Virtual FunctionsVirtual Functions

–– Template classesTemplate classes

–– ExceptionsExceptions

2

Page 3: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Classes and class members

3

structstruct DateStruct { int nMonth; int nDay; int nYear; }; // Here is a function to initialize a date// Here is a function to initialize a date void SetDate(DateStruct &sDate, int nMonth, int nDay, int nYear) { sDate.nMonthsDate.nMonth = nMonth; sDate.nDay = nDay; sDate.nYear = nYear; } // … In main …// … In main … DateStructDateStruct sToday; // Initialize it manually// Initialize it manually sToday.nMonth = 10; sToday.nDay = 14; sToday.nYear = 2040; SetDateSetDate((sTodaysToday, , 1010, , 1414, , 20202020););

Page 4: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Classes and class members

4

struct DateStruct { int nMonth; int nDay; int nYear; };

classclass DateDate

{{ publicpublic:: intint m_nMonthm_nMonth;; intint m_nDaym_nDay;; intint m_nYearm_nYear;; };}; Date cToday; // declare a // declare a ObjectObject of of classclass DateDate // Assign values to our members using the member selector operator (.)// Assign values to our members using the member selector operator (.) cToday.m_nMonth = 10; cToday.m_nDay = 14; cToday.m_nYear = 2020;

Page 5: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Classes and class members

5

structstruct DateStruct {{ int nMonth; int nDay; int nYear; };}; // Here is a function to initialize a date// Here is a function to initialize a date void SetDate(DateStruct &sDate, int nMonth, int nDay, int nYear) { sDate.nMonthsDate.nMonth = nMonth; sDate.nDay = nDay; sDate.nYear = nYear; } DateStructDateStruct sToday; SetDateSetDate((sTodaysToday, , 1010, , 1414, , 20202020););

classclass Date {{ public:public: int m_nMonth; int m_nDay; int m_nYear; // Member function// Member function void void SetDateSetDate((intint nMonthnMonth, , intint nDaynDay, , intint nYearnYear)) {{ m_nMonthm_nMonth = = nMonthnMonth;; m_nDaym_nDay = = nDaynDay;; m_nYearm_nYear = = nYearnYear;; }} };}; DateDate cToday; // call // call SetDateSetDate() on () on cTodaycToday cToday.SetDate(10, 14, 2020);

Page 6: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Classes and class members

6

#include #include <iostream> classclass EmployeeEmployee { publicpublic: char m_strName[25]; int m_nID; double m_dWage; // // Set the employee informationSet the employee information void SetInfo(char *strName, int nID, double dWage) { strncpy(m_strName, strName, 25); m_nID = nID; m_dWage = dWage; } // // Print employee information to the screenPrint employee information to the screen void Print() { using namespace std; cout << "Name: " << m_strName << " Id: " << m_nID << " Wage: $" << m_dWage << endl; } };

EmployeeEmployee cAlex; cAlex.SetInfocAlex.SetInfo("Alex", ("Alex", 11, , 2525..0000);); EmployeeEmployee cJoe; cJoe.SetInfo("Joe", 2, 22.25); cAlex.PrintcAlex.Print();(); cJoe.Print();

Page 7: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Public vs private access specifiers

7

classclass Access { int m_nA; // private by default// private by default int GetA() { return m_nA; } // private by default// private by default private:private: int m_nB; // private// private int GetB() { return m_nB; } // private// private protected:protected: int m_nC; // protected// protected int GetC() { return m_nC; } // protected// protected public:public: int m_nD; // public// public int GetD() { return m_nD; } // public// public };

AccessAccess cAccess; // ok because // ok because m_nDm_nD is publicis public cAccess.m_nD = 5; // ok because // ok because GetDGetD() is public() is public std::cout << cAccess.GetD(); // WRONG because // WRONG because m_nAm_nA is privateis private cAccess.m_nA = 2; // WRONG because // WRONG because GetBGetB() is private() is private std::cout << cAccess.GetB();

Page 8: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Access functions and encapsulation

8

classclass Date {

private:private: intint m_nMonth; intint m_nDay; intint m_nYear;

public:public: // Getters// Getters int GetGetMonth() { returnreturn m_nMonth; } int GetDay() { returnreturn m_nDay; } int GetYear() { returnreturn m_nYear; } // Setters// Setters voidvoid SetSetMonth(intint nMonth) { m_nMonth = nMonth; } voidvoid SetDay(int nDay) { m_nDay = nDay; } voidvoid SetYear(int nYear) { m_nYear = nYear; } };

Page 9: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Public vs private access specifiers

9

classclass Change {

public:public: intint m_nValuem_nValue;; }; int main() { Change cChange; cChange.m_nValuecChange.m_nValue = = 55;; std::cout << cChange.m_nValuecChange.m_nValue << std::endl; };

classclass Change { private:private: intint m_nValuem_nValue;; public:public: void void SetValueSetValue((intint nValuenValue) { ) { m_nValuem_nValue = = nValuenValue; }; } intint GetValueGetValue() { return () { return m_nValuem_nValue; }; } }; int main() { Change cChange; cChange.SetValuecChange.SetValue((55);); std::cout << cChange.GetValuecChange.GetValue() () << std::endl; }

Page 10: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors

• A constructorconstructor is a special kind of classclass membermember functionfunction that is executedexecuted whenwhen anan objectobject ofof thatthat classclass isis instantiatedinstantiated

• Constructors are typically used to initializeinitialize membermember variablesvariables of the class to appropriate default values, oror toto allowallow thethe useruser toto easilyeasily initializeinitialize thosethose membermember variablesvariables to whatever values are desired

• Constructors have specific rules for how they must be named: – Constructors should always have the same name as the class always have the same name as the class – Constructors havehave nono returnreturn typetype (not(not eveneven void)void)

• A constructorconstructor thatthat takestakes nono parametersparameters (or has all optional

parameters) is called a defaultdefault constructorconstructor

10

Page 11: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors

11

class FractionFraction { private: int m_nNumerator; int m_nDenominator; public:

Fraction()Fraction() // default constructor// default constructor

{ m_nNumerator = 0; m_nDenominator = 1; } int GetNumerator() { return m_nNumerator; } int GetDenominator() { return m_nDenominator; } // …// … };

Fraction Fraction cDefaultcDefault; ; // calls Fraction() constructor// calls Fraction() constructor

Page 12: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors with parameters

12

class FractionFraction { private: int m_nNumerator; int m_nDenominator; public:

Fraction()Fraction() { // default constructor// default constructor m_nNumerator = 0; m_nDenominator = 1; } // // Constructor with parametersConstructor with parameters

FractionFraction((intint nNumeratornNumerator, , intint nDenominatornDenominator = = 11)) { assert(nDenominator != 0); m_nNumerator = nNumerator; m_nDenominator = nDenominator; } int GetNumerator() { return m_nNumerator; } int GetDenominator() { return m_nDenominator; } // …// … };

Fraction Fraction cDefaultcDefault; ; // calls Fraction() constructor// calls Fraction() constructor Fraction Fraction cFiveThirdscFiveThirds((55, , 33); ); // calls Fraction(// calls Fraction(intint, , intint) constructor) constructor Fraction Six(Fraction Six(66); ); // calls Fraction(// calls Fraction(intint, , intint) constructor) constructor

Page 13: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Private constructors

13

class Book { private: int m_nPages; // This constructor can only be used by Book's members// This constructor can only be used by Book's members Book()Book() // private default constructor// private default constructor { m_nPages = 0; } public: // This constructor can be used by anybody// This constructor can be used by anybody Book(Book(intint nPagesnPages) ) // public non// public non--default constructordefault constructor { m_nPages = nPages; } }; Book Book cMyBookcMyBook; ; // fails because default constructor Book() is private// fails because default constructor Book() is private

Book Book cMyOtherBookcMyOtherBook((242242); ); // ok because Book(// ok because Book(intint) is public) is public

Page 14: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructor chaining issues

14

class Foo { public: FooFoo() () { // code to do A// code to do A } FooFoo((intint nValuenValue)) { // code to do A// code to do A // code to do B// code to do B } };

class Foo { public: FooFoo()() { Init();Init(); } FooFoo((intint nValuenValue)) { Init();Init(); // code to do B// code to do B } void Init()void Init() { // code to do A// code to do A } };

// C++// C++1111 : : // delegating constructors// delegating constructors class Foo { public: FooFoo()() { // code to do A// code to do A } FooFoo((intint nValuenValue) : ) : FooFoo()() { // code to do B// code to do B } };

Page 15: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Destructors • destructor is called when an object is destroyedwhen an object is destroyed

• Like constructors, destructors have specific

naming rules: – The destructor must have the same name as the the same name as the

class, preceded by a tilde (~)class, preceded by a tilde (~)

– The destructor can not take argumentscan not take arguments • implies that only one destructor may exist per classone destructor may exist per class, as

there is no way to overload destructorsno way to overload destructors since they can not be differentiated from each other based on arguments

– The destructor has no return typehas no return type

15

Page 16: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Destructors

16

classclass MyString { privateprivate: char *m_pchString; int m_nLength; public:public: MyStringMyString(const char *(const char *pchStringpchString="") ="") { m_nLength = strlen(pchString) + 1; //Plus one character for a terminator//Plus one character for a terminator m_pchString = new char[m_nLength]; strncpy(m_pchString, pchString, m_nLength); m_pchString[m_nLength-1] = '\0'; // Make sure the string is terminated// Make sure the string is terminated }

~~MyStringMyString() { () { // destructor// destructor delete[] delete[] m_pchStringm_pchString; ; // We need to // We need to deallocatedeallocate our bufferour buffer m_pchStringm_pchString = = 00; ; // Set // Set m_pchStringm_pchString to null just in caseto null just in case }} char* GetString() { return m_pchString; } int GetLength() { return m_nLength; } };

int main() { MyStringMyString cMyName("Alex"); // call constructor// call constructor std::cout << "My name is: " << cMyName.GetString(); return 0; } // // cMyNamecMyName destructor called here!destructor called here!

Page 17: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The hidden “this” pointer

17

class Simple { private: intint m_nIDm_nID;; public: Simple(int nID) { SetID(nID); } void SetID(int nID) {thisthis--> > m_nID = nID; } int GetID() { return thisthis-->>m_nID; } };

void SetID(int nID) { m_nID = nID; } // becomes (by compiler):// becomes (by compiler): void SetID(Simple* const thisSimple* const this, int nID) { thisthis-->>m_nID = nID; }

Page 18: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The hidden “this” pointer

18

class Calc { private: int m_nValue; public: Calc() { m_nValue = 0; } void Add(int nValue) { m_nValue += nValue; } void Sub(int nValue) { m_nValue -= nValue; } void Mult(int nValue) { m_nValue *= nValue; } int GetValue() { return m_nValue; } };

Calc cCalc; cCalc.Add(5); cCalc.Sub(3); cCalc.Mult(4);

Page 19: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The hidden “this” pointer

19

class Calc { private: int m_nValue; public: Calc() { m_nValue = 0; } Calc&Calc& Add(int nValue) { m_nValue += nValue; return *this; return *this; } Calc& Sub(int nValue) { m_nValue -= nValue; return *this; } Calc& Mult(int nValue) { m_nValue *= nValue; return *this; } int GetValue() { return m_nValue; } };

Calc cCalc; cCalc.AddcCalc.Add((55).Sub().Sub(33).).MultMult((44););

Page 20: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class code and header files

20

class Date { private: int m_nMonth; int m_nDay; int m_nYear; Date() { } Date() { } // private default constructor// private default constructor public: DateDate(int nMonth, int nDay, int nYear) { SetDate(nMonth, nDay, nYear); } void SetDate(int nMonth, int nDay, int nYear) { m_nMonth = nMonth; m_nDay = nDay; m_nYear = nYear; } int GetMonth() { return m_nMonth; } int GetDay() { return m_nDay; } int GetYear() { return m_nYear; } };

// // Date.hDate.h ##ifndefifndef DATE_HDATE_H #define DATE_H#define DATE_H // class interface// class interface // class declaration// class declaration ##endifendif

// Date.cpp// Date.cpp // class implementation// class implementation

Page 21: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class code and header files

21

////Date.hDate.h ##ifndefifndef DATE_HDATE_H #define DATE_H#define DATE_H class Date class Date { privateprivate: int m_nMonth; int m_nDay; int m_nYear; Date() ;Date() ; publicpublic: Date(Date(intint nMonthnMonth, , intint nDaynDay, , intint nYearnYear);); void void SetDateSetDate((intint nMonthnMonth, , intint nDaynDay, , intint nYearnYear);); intint GetMonthGetMonth() ;() ; intint GetDayGetDay()() ;; intint GetYearGetYear() ;() ; }; ##endifendif

Page 22: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class code and header files

22

//Date.cpp//Date.cpp #include "#include "Date.hDate.h"" // Date constructor// Date constructor Date::Date(){}Date::Date(){} Date::Date::Date(int nMonth, int nDay, int nYear) { SetDate(nMonth, nDay, nYear); } // Date member function// Date member function void Date::Date::SetDate(int nMonth, int nDay, int nYear) { m_nMonth = nMonth; m_nDay = nDay; m_nYear = nYear; } int Date:: Date:: GetMonth() { return m_nMonth; } int Date:: Date:: GetDay() { return m_nDay; } int Date:: Date:: GetYear() { return m_nYear; } };

Page 23: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

• If a class is not initialized using aa parameterizedparameterized constructor,constructor, aa

publicpublic defaultdefault constructorconstructor mustmust bebe providedprovided — if no public

default constructor is provided in this case, a compiler error will occur

• Once a constconst classclass objectobject hashas beenbeen initializedinitialized viavia constructorconstructor, any attemptattempt toto modifymodify the member variables of the object is disalloweddisallowed

23

constconst intint nValuenValue = = 55; ; // initialize explicitly// initialize explicitly constconst intint nValuenValue22((77); ); // initialize // initialize implictlyimplictly constconst Date Date cDatecDate; ; // initialize using default constructor// initialize using default constructor constconst Date cDateDate cDate22((1010, , 1616, , 20202020); ); // initialize using parameterized constructor// initialize using parameterized constructor

Page 24: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

24

class Something { public: int m_nValue; Something() { m_nValue = 0; } void ResetValue() { m_nValue = 0; } void SetValue(int nValue) { m_nValue = nValue; } int GetValue() { return m_nValue; } }; int main() { constconst Something cSomething; // calls default constructor// calls default constructor cSomething.m_nValuem_nValue = 5; // Error: violates const// Error: violates const cSomething.ResetValueResetValue(); // Error: violates const// Error: violates const cSomething.SetValueSetValue(5); // Error: violates const// Error: violates const std::cout << cSomething.GetValueGetValue(); // Error !!!// Error !!! }

Page 25: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

•• constconst classclass objectsobjects cancan onlyonly callcall constconst membermember functionsfunctions, GetValue() has not been marked as a const member function. A constconst membermember functionfunction is a member function that guarantees itit willwill notnot changechange anyany classclass variablesvariables oror callcall anyany nonnon--constconst membermember functionsfunctions

25

class Something { int m_nValue; public: /*…*//*…*/

int GetValue() constconst { return m_nValue; }

}; int main() { constconst Something cSomething; std::cout << cSomething.GetValueGetValue(); // Ok// Ok }

Page 26: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

26

class Something { int m_nValue; public: /*…*//*…*/

int GetValue() constconst;

};

int Something ::GetValue() constconst { return m_nValue; } int main() { constconst Something cSomething; std::cout << cSomething.GetValueGetValue(); // Ok// Ok }

Page 27: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

•• NoteNote thatthat constructorsconstructors shouldshould notnot bebe markedmarked asas constconst. This is because const objects should initialize their member variables, and a const constructor would not be able to do so

• ResetValue() has been marked as a const member function, but it attempts to change m_nValue. ThisThis willwill causecause aa compilercompiler errorerror

27

class Something { int m_nValue; public: /*…*//*…*/

void ResetValue () constconst {m_nValue = 0 ; }

};

Page 28: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Const class objects and member functions

• although it is not done very often, itit isis possiblepossible toto overloadoverload aa functionfunction inin suchsuch aa wayway toto havehave aa constconst andand nonnon--constconst versionversion ofof thethe samesame functionfunction

28

class Something { int m_nValue; public: Something(){} const const intint& & GetValue() constconst { return m_nValue; } intint&& GetValue() { return m_nValue; } }; SomethingSomething cSomething; cSomething.GetValue(); // calls non// calls non--const const GetValueGetValue();(); const Something const Something cSomething2; cSomething2.GetValue(); // calls const // calls const GetValueGetValue();();

Page 29: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Static member variables

•• file scope and the static keywordfile scope and the static keyword

29

int GenerateID() { static static intint s_nIDs_nID = = 00;; return s_nID++; } int main() { std::cout << GenerateIDGenerateID() () << std::endl; // // 00 std::cout << GenerateIDGenerateID()() << std::endl; // // 11 std::cout << GenerateIDGenerateID() () << std::endl; // // 22 return 0; }

Page 30: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Static member variables

30

class Something { private: int m_nValue; public: Something(int value) { m_nValue = value; } int GetValue() {return m_nValue;} }; int main() { Something cFirst(1); Something cSecond(2); coutcout <<<<cFirst.GetValuecFirst.GetValue()() << << cSecond.GetValuecSecond.GetValue(); // (); // 1212 return 0; }

class Something { public: static static intint s_nValues_nValue;; }; intint Something::Something::s_nValues_nValue = = 11;; int main() { Something cFirst; cFirst.s_nValuecFirst.s_nValue = = 22;; Something cSecond; cout << cSecond.s_nValuecSecond.s_nValue << cFirst.s_nValuecFirst.s_nValue; // // 2222 return 0; }

Page 31: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Static member variables • Although you can access static members through objects of

the class type: – this is somewhat misleading. cFirstcFirst..s_nValues_nValue impliesimplies thatthat s_nValues_nValue

belongsbelongs toto cFirstcFirst,, andand thisthis isis reallyreally notnot thethe casecase

– s_nValue does not belong to any object. In fact, In fact, s_nValues_nValue exists even exists even if there are no objects of the class have been instantiated!if there are no objects of the class have been instantiated!

• it is better to think of staticstatic membersmembers asas belongingbelonging toto thethe classclass itself,itself, notnot thethe objectsobjects ofof thethe classclass. Because s_nValue exists independently of any class objects, it can be accessed directly using the class name and the scope operator:

31

class SomethingSomething { public: static static intint s_nValues_nValue;; };

int main() { SomethingSomething::::s_nValues_nValue = = 22;; std::cout << Something::Something::s_nValues_nValue; }

Page 32: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

An example of Static member variables

32

class Something { private: staticstatic int s_nIDGenerator; int m_nID; public: Something() { Something() { m_nIDm_nID = = s_nIDGenerators_nIDGenerator++; }++; } int GetID() constconst { return m_nID; } }; int Something::s_nIDGenerator = 1; int main() { Something cFirst; Something cSecond; Something cThird; cout << cFirst.GetIDcFirst.GetID() () << endl; cout << cSecond.GetIDcSecond.GetID() () << endl; cout << cThird.GetIDcThird.GetID() () << endl; return 0; }

Page 33: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class in UML Class Diagrams

• A class in an object oriented system provides a crispcrisp abstractionabstraction of a well defined set of responsibilitiesresponsibilities

•• visvis = visibility= visibility –– + + denotes public attributes or operations

–– -- denotes private attributes or operations

–– ## denotes protected attributes or operations

•• attributeattribute = data member (aka fieldfield)

•• operationoperation = methodmethod (or constructorconstructor)

•• static members static members are indicated by underliningunderlining

33

ClassNameClassName

visvis attributeattribute :: typetype

visvis operationoperation((argarg listlist) :) : return typereturn type

Page 34: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class in UML Class Diagrams

34

Page 35: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exercises •• writing a singleton classwriting a singleton class

•• DesignDesign aa classclass diagramdiagram forfor modelingmodeling relationshiprelationship betweenbetween studentstudent andand theirtheir currentcurrent semestersemester coursescourses

–– Noun/verbNoun/verb analysisanalysis (Grammatical(Grammatical Parsing)Parsing)

•• LookLook forfor nounsnouns oror nounnoun phrasesphrases -- thesethese areare candidatecandidate classesclasses oror attributesattributes

•• LookLook forfor verbsverbs oror verbverb phrasesphrases -- thesethese areare candidatecandidate responsibilitiesresponsibilities oror operationsoperations ((InformationInformation expertexpert))

35

Page 36: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Friend functions

36

class Accumulator { private: int m_nValue; public: Accumulator() { m_nValue = 0; } void Add(int nValue) { m_nValue += nValue; } // Make the Reset() function a friend of this class// Make the Reset() function a friend of this class

friendfriend void Reset(Accumulator &cAccumulator);

}; // Reset() does not have a *this pointer// Reset() does not have a *this pointer // Reset() is now a friend of the Accumulator class// Reset() is now a friend of the Accumulator class void Reset(Accumulator &Accumulator &cAccumulatorcAccumulator) { // can access the private data of Accumulator objects// can access the private data of Accumulator objects cAccumulator.m_nValuecAccumulator.m_nValue = = 00;; }

Page 37: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Friend functions

37

// A function can be a friend of more than one class// A function can be a friend of more than one class class Humidity;class Humidity; class Temperature { int m_nTemp; public: Temperature(int nTemp) { m_nTemp = nTemp; } friendfriend void PrintWeatherPrintWeather(Temperature &cTemperature, Humidity &cHumidity); }; class Humidity { int m_nHumidity; public: Humidity(int nHumidity) { m_nHumidity = nHumidity; } friend friend void PrintWeatherPrintWeather(Temperature &cTemperature, Humidity &cHumidity); }; void PrintWeatherPrintWeather(Temperature &cTemperature, Humidity &cHumidity) { std::cout << cTemperature.m_nTempcTemperature.m_nTemp << cHumidity.m_nHumiditycHumidity.m_nHumidity << std::endl; }

Page 38: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Friend classes

38

class class Display;Display; class Storage { int m_nValue; double m_dValue; public: Storage(int nValue, double dValue) { m_nValue = nValue; m_dValue = dValue; } // Make the Display class a friend of Storage// Make the Display class a friend of Storage

friendfriend classclass Display;

};

class Display class Display { /* … *//* … */

public: Display() { } void DisplayItem(Storage &cStorage) { cout << cStorage.m_nValuecStorage.m_nValue << " " << cStorage.m_dValuecStorage.m_dValue; } };

Storage cStorage(5, 6.7); Display cDisplay(); cDisplay.DisplayItem(cStorage);

Page 39: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

class Display; class Storage { int m_nValue; double m_dValue; public: Storage(int nValue, double dValue) { m_nValue = nValue; m_dValue = dValue; } friend class Display; }; class Display { /* … */ public: Display() { } void DisplayItem(Storage &Storage &cStoragecStorage) { cout << cStorage.m_nValue << " " << cStorage.m_dValue; } };

Friend classes

39

Storage Storage

-- m_dValuem_dValue::: : doubledouble -- m_nValuem_nValue :: intint

+ Storage(+ Storage(intint nValuenValue, double , double dValuedValue))

Display Display

+ + Display() Display() + + DisplayItemDisplayItem(Storage &(Storage &cStoragecStorage) : void) : void

DependencyDependency is aa weakerweaker formform ofof relationshiprelationship which indicates that one class depends on another because it uses it at some point in time. OneOne classclass dependsdepends onon anotheranother ifif thethe independentindependent classclass isis aa parameterparameter variablevariable oror locallocal variablevariable ofof aa methodmethod ofof thethe dependentdependent classclass

Page 40: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Anonymous variables and objects

40

int Add(int nX, int nY) { int nSum = nX + nY; return return nSumnSum;; } // An// An anonymous variableanonymous variable is a variable that is given no nameis a variable that is given no name int AnonymousAdd(int nX, int nY) { return return nXnX + + nYnY;; } int main() { cout << Add(Add(55, , 33);); cout << AnonymousAddAnonymousAdd ((55, , 33);); }

Page 41: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Anonymous variables and objects

41

class Cents{ int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } int GetCents() { return m_nCents; } }; Cents Add(Cents &c1, Cents &c2) { Cents cTemp(c1.GetCents() + c2.GetCents()); return return cTempcTemp;; } int main() { Cents cCents1(6); Cents cCents2(8); Cents cCentsSum = Add(cCentsAdd(cCents11, cCents, cCents22)); cout << "I have " << cCentsSum.GetCentscCentsSum.GetCents() () << " cents."; }

Page 42: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Anonymous variables and objects

42

class Cents { int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } int GetCents() { return m_nCents; } }; Cents Add(Cents &c1, Cents &c2) { return CentsCents(c1.GetCents() + c2.GetCents()); } int main() { Cents cCents1(6); Cents cCents2(8); cout << "I have " << Add(cCentsAdd(cCents11, cCents, cCents22).).GetCentsGetCents() () << " cents."; }

Cents cCents(5); // normal variable// normal variable // // initialize it and then destroy itinitialize it and then destroy it Cents(Cents(77); ); // // anonymousanonymous variablevariable Cents(Cents(1010).).GetCentsGetCents()(); ; // // 1010

Page 43: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the arithmetic operators •• OperatorOperator overloadingoverloading allows the programmer to

define how operators (suchsuch asas +,+, --,, ==,==, =,=, andand !!) should interact with various data types

•• Operators as functionsOperators as functions – When you see the expression nXnX ++ nYnY, you can

translate this in your head to operator+(operator+(nXnX,, nYnY)) –– function overloading function overloading is used to resolve the function

calls to different versions of the function

• you can onlyonly overloadoverload thethe operatorsoperators thatthat existexist

– You cancan notnot createcreate newnew operatorsoperators • e.g., you could not create an operator ** to do exponents

43

Page 44: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the arithmetic operators

44

class Cents { int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } // Add Cents + Cents// Add Cents + Cents friendfriend Cents operator+operator+(const Cents &c1, const Cents &c2); int GetCents() { return m_nCents; } }; // note: this function is not a member function!// note: this function is not a member function! Cents operator+operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(// use the Cents constructor and operator+(intint, , intint)) return Cents(c1.m_nCents + c2.m_nCents); } int main() { Cents cCents1(6); Cents cCents2(8); Cents cCentsSum = cCentscCents1 1 + cCents+ cCents22; std::cout << "I have " << cCentsSumcCentsSum ..GetCentsGetCents() () << " cents." ; }

(cCentscCents1 1 + cCents+ cCents22) .GetCentsGetCents(); ();

Page 45: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the arithmetic operators

45

class Cents { int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } // Add Cents + Cents// Add Cents + Cents friendfriend Cents operator+operator+(const Cents &c1, const Cents &c2); int GetCents() { return m_nCents; } }; // note: this function is not a member function!// note: this function is not a member function! Cents operator+operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(// use the Cents constructor and operator+(intint, , intint)) return Cents(c1.m_nCents + c2.m_nCents); } int main() { Cents cCents1(6); Cents cCents2(8); Cents cCentsSum = cCentscCents1 1 + cCents+ cCents22; std::cout << "I have " << cCentsSumcCentsSum ..GetCentsGetCents() () << " cents." ; }

When the operator does notnot modifymodify itsits operandsoperands, operator can overloading via friendfriend functionfunction. OverloadingOverloading operatorsoperators usingusing membermember functionsfunctions isis betterbetter optionoption

Page 46: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the arithmetic operators

46

class Cents { int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } friendfriend Cents operator+operator+(const Cents &c1, const Cents &c2); friendfriend Cents operatoroperator--(const Cents &c1, const Cents &c2); int GetCents() { return m_nCents; } }; // note: this function is not a member function!// note: this function is not a member function! Cents operator+operator+(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator+(// use the Cents constructor and operator+(intint, , intint)) return Cents(c1.m_nCents + c2.m_nCents); } // note: this function is not a member function!// note: this function is not a member function! Cents operatoroperator--(const Cents &c1, const Cents &c2) { // use the Cents constructor and operator// use the Cents constructor and operator--((intint, , intint)) return Cents(c1.m_nCents - c2.m_nCents); }

Overloading the multiplication operator and division operator are as easy as defining : •• operator*operator* •• operator/operator/

Page 47: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading operators for operands of different types

47

class Cents { int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } // Overload // Overload cCentscCents + + intint friend Cents operator+(const Cents &cCents, intint nCentsnCents); // Overload // Overload intint + + cCentscCents friend Cents operator+(intint nCentsnCents, const Cents &cCents); int GetCents() { return m_nCents; } }; // note: this function is not a member function!// note: this function is not a member function! Cents operator+(const Cents &cCents, intint nCentsnCents) { return Cents(cCents.m_nCents + nCents); } // note: this function is not a member function!// note: this function is not a member function! Cents operator+(intint nCentsnCents, const Cents &cCents) { return Cents(cCents.m_nCents + nCents); }

Cents cCents c1 1 = Cents(= Cents(44) + ) + 66;; Cents cCents c2 2 = = 6 6 + Cents(+ Cents(44););

Page 48: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the I/O operators

48

class Point { double m_dX, m_dY, m_dZ; public: Point(double dX=0.0, double dY=0.0, double dZ=0.0) { m_dX = dX; m_dY = dY; m_dZ = dZ; } double GetX() { return m_dX; } double GetY() { return m_dY; } double GetZ() { return m_dZ; } }; int main() { Point cPoint(5.0, 6.0, 7.0); cout << "(" << cPoint.GetX() << ", " << cPoint.GetY() << ", " << cPoint.GetZ() << ")"; }

Point Point cPointcPoint((55..00, , 66..00, , 77..00);); cout << cout << cPointcPoint;;

Page 49: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the I/O operators

49

class Point { double m_dX, m_dY, m_dZ; public: Point(double dX=0.0, double dY=0.0, double dZ=0.0) { m_dX = dX; m_dY = dY; m_dZ = dZ; } friend friend ostreamostream& & operator<< (operator<< (ostreamostream &&out, out, Point &Point &cPointcPoint);); double GetX() { return m_dX; } double GetY() { return m_dY; } double GetZ() { return m_dZ; } }; ostreamostream& & operator<< (operator<< (ostreamostream &&out, out, Point &Point &cPointcPoint) ) { out << "(" << cPoint.m_dX << ", " << cPoint.m_dY << ", " << cPoint.m_dZ << ")"; return out;return out; }

Point cPoint1(2.0, 3.0, 4.0); Point cPoint2(6.0, 7.0, 8.0); coutcout << cPoint<< cPoint1 1 << " " << cPoint<< " " << cPoint2 2 << << endlendl;;

Page 50: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the I/O operators

50

class Point { double m_dX, m_dY, m_dZ; public: Point(double dX=0.0, double dY=0.0, double dZ=0.0) { m_dX = dX; m_dY = dY; m_dZ = dZ; } friendfriend istreamistream&& operator>> operator>> (istreamistream &&in, Point &Point &cPoint); double GetX() { return m_dX; } double GetY() { return m_dY; } double GetZ() { return m_dZ; } }; istreamistream&& operator>> operator>> (istreamistream &&in, Point &Point &cPoint) { in >> cPoint.m_dX; in >> cPoint.m_dY; in >> cPoint.m_dZ; return in;return in; }

Point cPoint; cincin >> >> cPointcPoint;; Point cPoint1, cPoint2; cincin >> cPoint>> cPoint1 1 >> cPoint>> cPoint22;;

Page 51: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the comparison operators

51

class Point { double m_dX, m_dY, m_dZ; public: Point(double dX=0.0, double dY=0.0, double dZ=0.0) { /* … */{ /* … */ }} friendfriend bool operator== operator== (Point &cP1, Point &cP2); friendfriend bool operator!= operator!= (Point &cP1, Point &cP2); friendfriend bool operator> operator> (Point &cP1, Point &cP2); friendfriend bool operator<= operator<= (Point &cP1, Point &cP2); friendfriend bool operator<operator< (Point &cP1, Point &cP2); friendfriend bool operator>= operator>= (Point &cP1, Point &cP2); /* … *//* … */ }; bool operator== operator== (Point &cP1, Point &cP2) { return (cP1.m_dX == cP2.m_dX && cP1.m_dY == cP2.m_dY && cP1.m_dZ == cP2.m_dZ); } bool operator!= operator!= (Point &cP1, Point &cP2) { return !(cP1 == cP2); } /* … *//* … */

Page 52: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading unary operators

52

// positive (+), negative (// positive (+), negative (--) and logical not (!)) and logical not (!) class Point { double m_dX, m_dY, m_dZ; public: Point(double dX=0.0, double dY=0.0, double dZ=0.0) { /* … *//* … */ } friendfriend Point operatoroperator-- (const Point &cPoint); friendfriend bool operator!operator! (const Point &cPoint); /* … *//* … */ }; Point operatoroperator-- (const Point &cPoint) { return Point(-cPoint.m_dX, -cPoint.m_dY, -cPoint.m_dZ); } bool operator!operator! (const Point &cPoint){ return (cPoint.m_dX == 0.0 && cPoint.m_dY == 0.0 && cPoint.m_dZ == 0.0); }

Point cPoint; // use default // use default contructorcontructor to set to (to set to (00..00, , 00..00, , 00..00)) if (!if (!cPointcPoint) …) …

Page 53: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading operators using member functions

• When overloading an operator using a member function: – The leftmostleftmost operandoperand of the overloaded operator mustmust bebe

anan objectobject ofof thethe classclass typetype – The leftmost operand leftmost operand becomes the implicit *this implicit *this

parameterparameter. All other operands become function All other operands become function parametersparameters

• Most operators can actually be overloaded either way, however there are a few exception few exception cases: –– If the leftmost operand is not a member of the class typeIf the leftmost operand is not a member of the class type

•• e.g., operator+(e.g., operator+(intint, , YourClassYourClass)), operator<<(operator<<(ostreamostream&, &, YourClassYourClass))

– The assignment (=)assignment (=), subscript ([])subscript ([]), call (())call (()), and member member selection (selection (-->)>) operators must be overloaded as member functions

53

Page 54: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading operators using member functions

54

class Cents { private: int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } friend Cents operator-(const Cents &cCents); friend Cents operator+(Cents &cCents, int nCents); }; // note: this function is not a member function!// note: this function is not a member function! Cents operator-(const Cents &cCents) { return Cents(-cCents.m_nCents); } Cents operator+(Cents &cCents, int nCents) { return Cents(cCents.m_nCents + nCents); }

Page 55: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading operators using member functions

55

class Cents { private: int m_nCents; public: Cents(int nCents) { m_nCents = nCents; } // Overload // Overload --cCentscCents : : --this this Cents operator-(); // Overload // Overload cCentscCents + + intint : this + : this + intint Cents operator+(int nCents); }; // note: the following functions are member function!// note: the following functions are member function! Cents CentsCents::operator::operator--() { return Cents(-m_nCents); } Cents CentsCents::operator+::operator+(int nCents) { return Cents(m_nCents + nCents); // this // this --> > m_nCentsm_nCents + …+ … }

Remember that C++ compiler internally converts Cents Cents CentsCents::operator::operator--(); (); to Cents operatorCents operator--(const Cents *this)(const Cents *this), which you will note is almost identical to our friend version Cents operator-(const Cents &cCents)!

Page 56: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading prefix increment and decrement

56

// overloaded exactly the same as any normal unary operator// overloaded exactly the same as any normal unary operator class Digit { int m_nDigit; public: Digit(int nDigit=0) { m_nDigit = nDigit; } Digit& operator++(); Digit& operator--(); int GetDigit() const { return m_nDigit; } }; Digit& Digit::operator++Digit::operator++() { if (m_nDigit == 9) m_nDigit = 0; else ++m_nDigit; return *this; return *this; // Note that we return *this// Note that we return *this } Digit& Digit::operatorDigit::operator----() { if (m_nDigit == 0) m_nDigit = 9; else --m_nDigit; return *this; return *this; // Note that we return *this// Note that we return *this }

Digit d; cout<< (++++d).cout<< (++++d).GetDigitGetDigit(); (); // // 22

Page 57: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading postfix increment and decrement

57

// uses a “dummy variable” or “dummy argument” for the postfix operators // uses a “dummy variable” or “dummy argument” for the postfix operators class Digit { int m_nDigit; public: Digit(int nDigit=0) { m_nDigit = nDigit; } Digit operator++operator++(intint); // postfix// postfix Digit operatoroperator----(intint); // postfix// postfix int GetDigit() const { return m_nDigit; } }; Digit DigitDigit::operator++::operator++(intint) { Digit cResult(m_nDigitm_nDigit); // a temporary variable with our current digit// a temporary variable with our current digit ++(*this);++(*this); // Use prefix operator to increment this digit// Use prefix operator to increment this digit return cResult; // return temporary result// return temporary result } Digit DigitDigit::operator::operator----(intint) { Digit cResult(m_nDigitm_nDigit); ----(*this);(*this); return cResult; }

Digit cDigit(5); ++++cDigitcDigit; ; // calls Digit::operator++();// calls Digit::operator++(); cDigitcDigit++; ++; // calls Digit::operator++(// calls Digit::operator++(intint););

Page 58: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the subscript operator

58

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.SetItemcMyList.SetItem((22, , 33);); return 0; }

Page 59: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the subscript operator

59

class IntList { private: int m_anList[10]; public: intint& & operator[]operator[] (const const intint nIndex); }; intint& & IntListIntList::::operator[]operator[] (const const intint nIndex) { return m_anList[nIndex]; } int main() { IntList cMyList; cMyListcMyList[[22] = ] = 33; ; // set a value// set a value cout << cMyListcMyList[[22]]; // get a value// get a value }

Why operator[] returns a reference?Why operator[] returns a reference?

Page 60: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the subscript operator

60

#include <cassert> // for assert()// for assert() class IntList { private: int m_anList[10]; public: intint& & operator[]operator[] (const const intint nIndex); }; intint& & IntListIntList::::operator[]operator[] (const const intint nIndex) { assert(assert(nIndexnIndex >= >= 0 0 && && nIndexnIndex < < 1010);); return m_anList[nIndex]; }

int anArray[5]; anArray[7] = 3; // index // index 7 7 is out of bounds!is out of bounds!

Page 61: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading the parenthesis operator

61

#include <cassert> // for assert()// for assert() class Matrix { double adData[4][4]; public: Matrix() { for (int nCol=0; nCol<4; nCol++) for (int nRow=0; nRow<4; nRow++) adData[nRow][nCol] = 0.0; } double& operator()operator()(const int nCol, const int nRow); void operator()operator()(); }; double& Matrix::operator()Matrix::operator()(const int nCol, const int nRow) { assert(assert(nColnCol >= >= 0 0 && && nColnCol < < 44); assert(); assert(nRownRow >= >= 0 0 && && nRownRow < < 44);); return adData[nRow][nCol]; } void Matrix::operator()()Matrix::operator()(){ for (int nCol=0; nCol<4; nCol++) for (int nRow=0; nRow<4; nRow++) adData[nRow][nCol] = 0.0; }

Matrix cMatrix; cMatrixcMatrix((11, , 22) = ) = 44..55;; std::cout << cMatrixcMatrix((11, , 22);); // // 44..55 cMatrixcMatrix(); (); // // eraseerase cMatrixcMatrix std::cout << cMatrixcMatrix((11, , 22);); // // 00

Page 62: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading typecasts

62

class Cents { int m_nCents; public: Cents(int nCents=0) { m_nCents = nCents; } int GetCents() { return m_nCents; } void SetCents(int nCents) { m_nCents = nCents; } }; void PrintInt(int nValue) { cout << nValue; } int main() { Cents cCents(7); PrintInt(cCents.GetCentscCents.GetCents()()); }

int nValue = 5; // // intint implicitly cast to a doubleimplicitly cast to a double double dValue = nValue; // our goal// our goal Cents cCents(7); PrintInt(cCentscCents); // // printprint 77 int nCents = static_caststatic_cast<<intint>(>(cCentscCents); ); PrintInt(nCents); // // printprint 77

Page 63: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading typecasts

63

/* Casting operators do not have a return type. C++ assumes you will be /* Casting operators do not have a return type. C++ assumes you will be returning the correct type */returning the correct type */ class Cents { private: int m_nCents; public: Cents(int nCents=0) { m_nCents = nCents; } // Overloaded // Overloaded intint castcast

operatoroperator intint() { return m_nCents; }

int GetCents() { return m_nCents; } void SetCents(int nCents) { m_nCents = nCents; } }; void PrintInt(intint nValue) { cout << nValue; }

Cents cCents(7);

PrintIntPrintInt((cCentscCents); ); // // printprint 77 intint nCentsnCents = = static_caststatic_cast<<intint>(>(cCentscCents););

PrintInt(nCents); // // printprint 77

Page 64: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overloading typecasts

64

class Cents class Cents { int m_nCents; public: /* … */ int GetCents() { return m_nCents; } }; ////////////////////////////////////////////////////////////////////////// class Dollars class Dollars { int m_nDollars; public: Dollars(int nDollars=0) { m_nDollars = nDollars; } // Allow us to convert Dollars into Cents// Allow us to convert Dollars into Cents operatoroperator CentsCents() { return Cents(m_nDollars * 100); } }; voidvoid PrintCentsPrintCents((Cents Cents cCentscCents)) { cout << cCents.GetCents(); }

Dollars cDollars(9); // // cDollarscDollars will be cast to a Centswill be cast to a Cents PrintCents(cDollarscDollars);

Page 65: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

copy constructor and overloading assignment operator

65

class Cents { int m_nCents; public: Cents(intint nCentsnCents==00) { m_nCents = nCents; } // Copy constructor// Copy constructor Cents(const Cents &const Cents &cSource) { m_nCents = cSource.m_nCents; } Cents& operator= operator= (const Cents &cSource); }; Cents& Cents::operator= Cents::operator= (const Cents &cSource) { // do the copy// do the copy m_nCents = cSource.m_nCents; // return the existing object// return the existing object return *this; return *this; // // cMarkcMark = = cNancycNancy = = cFredcFred = = cJoecJoe;; }

Cents cMark(5); // calls Cents constructor// calls Cents constructor Cents cNancy; // calls Cents default constructor// calls Cents default constructor cNancy = cMark; // calls Cents assignment operator// calls Cents assignment operator // note the following line// note the following line Cents cNancy = cMark; // calls Cents copy constructor!// calls Cents copy constructor!

Page 66: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

copy constructor and overloading assignment operator

• The assignmentassignment operatoroperator is used to copy the values from one object to another already existing object. The key words here are alreadyalready existingexisting – Cents cMark(5); // calls Cents constructor// calls Cents constructor – Cents cNancy; // calls Cents default constructor// calls Cents default constructor – cNancy = cMark; // calls Cents assignment operator// calls Cents assignment operator

• A copycopy constructorconstructor is a special constructor that

initializes aa newnew objectobject fromfrom anan existingexisting objectobject – Cents cNancy = cMark; // calls Cents copy constructor!// calls Cents copy constructor!

– Because the secondsecond statementstatement usesuses anan equalsequals symbolsymbol inin

it,it, youyou mightmight expectexpect thatthat itit callscalls thethe assignmentassignment operatoroperator.. However, it doesn’t! It actually calls a special type of constructor calledcalled aa copycopy constructorconstructor

66

Page 67: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

copy constructor and overloading assignment operator

• It is possible in C++ to do a selfself--assignmentassignment:

– cMark = cMark; //// validvalid assignmentassignment

•• toto dodo aa checkcheck forfor selfself--assignmentassignment atat thethe toptop ofof anan overloadedoverloaded assignmentassignment operatoroperator

67

Cents& Cents::operator=Cents::operator= (const Cents &cSource) { // check for self// check for self--assignment by comparing the address of theassignment by comparing the address of the ifif (this == &(this == &cSourcecSource) ) returnreturn *this;*this; m_nCents = cSource.m_nCents; return *this; }

Page 68: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

copy constructor and overloading assignment operator

• Just like defaultdefault constructorconstructor, C++ will provide a defaultdefault copycopy constructorconstructor if you do not provide one yourself. However, unlike other operators, C++ will provide a defaultdefault assignmentassignment operatoroperator if you do not provide one yourself!

• Because C++ does not know much about your class, the defaultdefault copycopy constructorconstructor andand defaultdefault assignmentassignment operatorsoperators itit providesprovides areare veryvery simplesimple. They use a copying method known as a memberwisememberwise copycopy (also known as a shallowshallow copycopy).

68

Page 69: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Shallow copying

• A shallowshallow copycopy means that C++ copies each member of the class individually usingusing thethe assignmentassignment operatoroperator. When classes are simple (eg. do not contain any dynamically allocated memory), this works very well:

69

class Cents { private: int m_nCents; public: Cents(int nCents=0) { m_nCents = nCents; } };

Page 70: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Shallow copying

70

class class MyStringMyString { char *char *m_pchString; int m_nLength; public: MyString(char *pchString="") // default constructor// default constructor { // Find the length of the string plus one character for a terminator// Find the length of the string plus one character for a terminator m_nLength = strlen(pchString) + 1; m_pchString= new char[new char[m_nLengthm_nLength];]; // Allocate a buffer equal to this length// Allocate a buffer equal to this length strncpy(m_pchString, pchString, m_nLength); m_pchString[m_nLength-1] = '\0'; // Make sure the string is terminated// Make sure the string is terminated } ~MyString() { // destructor // destructor delete[] delete[] m_pchStringm_pchString; ; // We need to // We need to deallocatedeallocate our bufferour buffer m_pchStringm_pchString = = 00; ; // Set // Set m_pchStringm_pchString to null just in caseto null just in case } char* GetString() { return m_pchString; } int GetLength() { return m_nLength; } };

MyString cHello("Hello, world!"); { MyString cCopy = cHello; // use default copy constructor// use default copy constructor } // // cCopycCopy goes out of scope heregoes out of scope here

std::cout << cHello.GetString(); // this will crash// this will crash

Page 71: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Shallow copying • This (MyStringMyString cCopycCopy == cHellocHello;;) seems harmless

enough as well, but it’s actually thethe sourcesource ofof ourour problem!problem!

• When this line is evaluated, C++ will useuse thethe defaultdefault copycopy constructorconstructor – because we haven’t provided our ownwe haven’t provided our own

– Because aa shallowshallow pointerpointer copycopy justjust copiescopies thethe addressaddress ofof

thethe pointerpointer

– the addressaddress ofof cHellocHello..m_pchStringm_pchString isis copiedcopied intointo cCopycCopy..m_pchStringm_pchString. As a result, cCopy.m_pchString and cHello.m_pchString are nownow bothboth pointingpointing toto thethe samesame piecepiece ofof memory!memory!

71

Page 72: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Shallow copying

• consider the following line –– }} // // cCopycCopy goes out of scope heregoes out of scope here

• When cCopycCopy goesgoes outout ofof scopescope, the MyString destructordestructor isis calledcalled onon cCopycCopy – The destructor deletes the dynamicallydynamically allocatedallocated

memorymemory thatthat bothboth cCopycCopy..m_pchStringm_pchString andand cHellocHello..m_pchStringm_pchString areare pointingpointing to!to!

– Consequently, by deleting cCopy, we’ve also (inadvertently) affected cHello. Note that the destructor will set cCopy.m_pchString to 0, but cHellocHello..m_pchStringm_pchString willwill bebe leftleft pointingpointing toto thethe deleteddeleted (invalid)(invalid) memory!memory!

72

Page 73: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Deep copying

73

class MyString { / * … */

public: // Copy constructor// Copy constructor

MyString(const const MyStringMyString& & cSource) { // because // because m_nLengthm_nLength is not a pointer, we can shallow copy itis not a pointer, we can shallow copy it m_nLength = cSource.m_nLength; // // m_pchStringm_pchString is a pointer, so we need to deep copy it if it is nonis a pointer, so we need to deep copy it if it is non--nullnull if (if (cSource.m_pchStringcSource.m_pchString)) { // allocate memory for our copy// allocate memory for our copy m_pchString = new char[new char[m_nLengthm_nLength]]; // Copy the string into our newly allocated memory// Copy the string into our newly allocated memory strncpy(m_pchString, cSource.m_pchString, m_nLength); } else m_pchStringm_pchString = = 00;; }

};

MyString cHello("Hello, world!"); { MyString cCopy = cHello; // use copy constructor// use copy constructor } // // cCopycCopy goes out of scope heregoes out of scope here std::cout << cHello.GetString();

Page 74: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Deep copying

• What happens when we do the following?

–– MyStringMyString cHellocHello("Hello, world!");("Hello, world!");

–– cHellocHello = = cHellocHello; ; // calls assignment operator// calls assignment operator

74

// Problematic assignment operator// Problematic assignment operator MyString& MyStringMyString::operator=::operator=(const MyString& cSource) {

// Note: No check for self// Note: No check for self--assignment!assignment! delete[] delete[] m_pchString; // // deallocatedeallocate any value that this string is holding!any value that this string is holding! // because // because m_nLengthm_nLength is not a pointer, we can shallow copy itis not a pointer, we can shallow copy it m_nLength = cSource.m_nLength; if (cSource.m_pchString) { m_pchString = new char[new char[m_nLengthm_nLength];]; // allocate memory for our copy// allocate memory for our copy strncpy(m_pchString, cSource.m_pchString, m_nLength); } else m_pchString = 0; return *this;return *this; }

Page 75: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Deep copying

• What happens when we do the following?

–– MyStringMyString cHellocHello("Hello, world!");("Hello, world!");

–– cHellocHello = = cHellocHello; ; // calls assignment operator// calls assignment operator

75

// Assignment operator// Assignment operator MyString& MyStringMyString::operator=::operator=(const MyString& cSource) {

if (this == &this == &cSourcecSource) return *this; // check for self// check for self--assignmentassignment delete[] m_pchString; // // deallocatedeallocate any value that this string is holding!any value that this string is holding! // because // because m_nLengthm_nLength is not a pointer, we can shallow copy itis not a pointer, we can shallow copy it m_nLength = cSource.m_nLength; // now we need to deep copy // now we need to deep copy m_pchStringm_pchString if (cSource.m_pchString) { m_pchString = new char[m_nLength]; // allocate memory for our copy// allocate memory for our copy strncpy(m_pchString, cSource.m_pchString, m_nLength); } else m_pchString = 0; return *this; }

Page 76: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Preventing copying

• C++ will not automatically create a default copy constructor and default assignment operator, because we’ve told the compiler we’re defining our own functions

76

class MyString { private:private: char *m_pchString; int m_nLength;

MyStringMyString(const (const MyStringMyString& & cSourcecSource);); MyStringMyString& & operator=operator=(const (const MyStringMyString& & cSourcecSource);); public: /*…*/ };

Page 77: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructor initialization lists

77

class Something { private: int m_nValue; double m_dValue; int *m_pnValue; public: Something() { m_nValuem_nValue = = 00;; m_dValuem_dValue = = 00..00;; m_pnValuem_pnValue = = 00;; } };

class Something { private: int m_nValue; double m_dValue; int *m_pnValue; public: Something() : : m_nValuem_nValue((00), ), m_dValuem_dValue((00..00), ), m_pnValuem_pnValue((00)) { } };

Page 78: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructor initialization lists

78

class Something { private: constconst int m_nValue; public: Something() { m_nValuem_nValue = = 55;; } };

class Something { private: constconst int m_nValue; public: Something() : : m_nValuem_nValue((55)) { } };

Page 79: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Aggregation

• A special form of association that specifies a wholewhole--partpart relationshiprelationship between the aggregate (whole) and a component part

•• nono ownershipownership betweenbetween thethe complexcomplex objectobject andand thethe subobjectssubobjects is implied

• When an aggregateaggregate isis destroyeddestroyed, the subobjectssubobjects areare notnot destroyeddestroyed

79

Page 80: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructor initialization lists

80

class Teacher { private: string m_strName; public: Teacher(string strName) : m_strName(strName) { } string GetName() { return m_strName; } }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class Department { private: Teacher *m_pcTeacher; // // This dept holds only one teacherThis dept holds only one teacher public: Department(Teacher *pcTeacher=NULL) : m_pcTeacher(pcTeacher) { } };

Page 81: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Aggregation

81

class Teacher { private: string m_strName; public: Teacher(string strName) : m_strName(strName) { } string GetName() { return m_strName; } }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class Department { private: Teacher *m_pcTeacher; // This dept holds only one teacher// This dept holds only one teacher public: Department(Teacher *pcTeacher=NULL) : m_pcTeacher(pcTeacher) { } };

// // Create a teacher outside the scope of the DepartmentCreate a teacher outside the scope of the Department Teacher *pTeacher = new Teacher("Bob"); // create a teacher { Department cDept(pTeacher); } // // cDeptcDept goes out of scope here and is destroyedgoes out of scope here and is destroyed // // pTeacherpTeacher still exists here because still exists here because cDeptcDept did not destroy itdid not destroy it delete pTeacher;

Page 82: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Composition

•• compositioncomposition:: building complex objects from simpler objects – you have a head, a body, some legs, arms, and …

• A form of aggregationaggregation with strongstrong ownershipownership and coincidentcoincident lifetimelifetime as part of the whole – A personal computer hashas--aa CPU, a motherboard, and

other components

• has a strong life cycle dependencylife cycle dependency –– compositioncomposition isis destroyeddestroyed, all of the subobjectssubobjects areare

destroyeddestroyed asas wellwell

82

Page 83: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Composition

83

#include "#include "CPU.hCPU.h"" #include "#include "Motherboard.hMotherboard.h"" #include "#include "RAM.hRAM.h"" class PC { private: CPU CPU m_cCPUm_cCPU;; Motherboard Motherboard m_cMotherboardm_cMotherboard;; RAM RAM m_cRAMm_cRAM;; }; PC::PersonalComputer( int nCPUSpeed, char *strMotherboardModel, int nRAMSize) : : m_cCPUm_cCPU((nCPUSpeednCPUSpeed), ), m_cMotherboardm_cMotherboard((strMotherboardModelstrMotherboardModel), ), m_cRAMm_cRAM((nRAMSizenRAMSize)) { }

Page 84: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Relationships

84

Page 85: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Introduction to inheritance

•• InheritanceInheritance involves creating new objects by directly acquiring the attributes and behaviors of other objects and then extendingextending oror specializingspecializing themthem

• an isis--aa relationshiprelationship between two classes

– C++ inherited many features from C

85

Fruit

Banana Apple

Shape

Triangle Rectangle

parentparent or basebase

childchild or derivedderived

Page 86: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Liskov substitution principle

• introduced by BarbaraBarbara LiskovLiskov in a 1987 –– SubstitutabilitySubstitutability is a principle in object-oriented

programming

• if SS isis aa subtypesubtype ofof T,T, thenthen objectsobjects ofof typetype TT maymay bebe replacedreplaced withwith objectsobjects ofof typetype SS without altering any of the desirable properties of that program –– PreconditionsPreconditions cannot be strengthenedstrengthened inin aa subtypesubtype

–– PostconditionsPostconditions cannot be weakenedweakened inin aa subtypesubtype

–– InvariantsInvariants of the supertype mustmust bebe preservedpreserved inin aa subtypesubtype

86

Page 87: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance

87

class PersonPerson { public: string m_strName; int m_nAge; bool m_bIsMale; string GetName() { return m_strName; } int GetAge() { return m_nAge; } bool IsMale() { return m_bIsMale; } Person(string strName = "", int nAge = 0, bool bIsMale = false) : m_strName(strName), m_nAge(nAge), m_bIsMale(bIsMale) { } }; // // BaseballPlayerBaseballPlayer publicly inheriting Personpublicly inheriting Person

class BaseballPlayer : public Person public Person { public: double m_dBattingAverage; int m_nHomeRuns; BaseballPlayer(double dBattingAverage = 0.0, int nHomeRuns = 0) : m_dBattingAverage(dBattingAverage), m_nHomeRuns(nHomeRuns) { } };

Page 88: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance

88

class PersonPerson { public: string m_strName; int m_nAge; bool m_bIsMale; string GetName() { return m_strName; } int GetAge() { return m_nAge; } bool IsMale() { return m_bIsMale; } Person(string strName = "", int nAge = 0, bool bIsMale = false) : m_strName(strName), m_nAge(nAge), m_bIsMale(bIsMale) { } }; // // BaseballPlayerBaseballPlayer publicly inheriting Personpublicly inheriting Person

class BaseballPlayer : public Person public Person { public: double m_dBattingAverage; int m_nHomeRuns; BaseballPlayer(double dBattingAverage = 0.0, int nHomeRuns = 0) : m_dBattingAverage(dBattingAverage), m_nHomeRuns(nHomeRuns) { } };

// Create a new // Create a new BaseballPlayerBaseballPlayer objectobject BaseballPlayer cJoe; cJoe.m_strNamem_strName = "Joe"; // Print out the name// Print out the name cout << cJoe.GetNameGetName() << std::endl;

Page 89: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance

89

class Employee { public: string m_strEmployerName; double m_dHourlySalary; long m_lEmployeeID; Employee(string strEmployerName, double dHourlySalary, long lEmployeeID) : m_strEmployerName(strEmployerName), m_dHourlySalary(dHourlySalary), m_lEmployeeID(lEmployeeID) { } double GetHourlySalary() { return m_dHourlySalary; } void PrintNameAndSalary() { cout << m_strName << ": " << m_dHourlySalary << std::endl; } };

class Supervisor: public Employee: public Employee { public: // This Supervisor can oversee a max of // This Supervisor can oversee a max of 5 5 employeesemployees int m_nOverseesIDs[5]; };

Page 90: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors and initialization of derived classes

90

class Base { public: int m_nValue; Base(int nValue=0) : m_nValue(nValue) { } };

class Derived: public Base: public Base { public: double m_dValue; Derived(double dValue=0.0) : m_dValue(dValue) { } };

Memory for cBase is set aside The appropriate Base constructor is called The initialization list initializes variables The body of the constructor executes Control is returned to the caller Memory for cDerived is set aside (enough for both the Base and Derived portions). The appropriate Derived constructor is called The Base object is constructed first using the appropriate Base constructor The initialization list initializes variables The body of the constructor executes Control is returned to the caller

int main() { Base cBase(5); Derived cDerived(1.3); }

Page 91: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors and initialization of derived classes

91

class Base { public: int m_nValue; Base(int nValue=0) : m_nValue(nValue) { } };

class Derived: : public Base public Base { public: double m_dValue; Derived(double dValue=0.0, int nValue=0) // // does not workdoes not work : m_dValue(dValue), m_nValue(nValue) { } };

C++ preventsprevents classesclasses fromfrom initializinginitializing inheritedinherited membermember variablesvariables inin thethe initializationinitialization

listlist ofof aa constructorconstructor. Why? The answer has to do with constconst andand referencereference variablesvariables. Consider what would happen if m_nValue were const. BecauseBecause constconst variablesvariables mustmust bebe initializedinitialized withwith aa valuevalue atat thethe timetime ofof creation,creation, thethe basebase classclass constructorconstructor mustmust setset it’sit’s valuevalue whenwhen thethe variablevariable isis createdcreated.. However,However, whenwhen thethe basebase classclass constructorconstructor finishes,finishes, thethe derivedderived classclass constructorsconstructors initializationinitialization listslists areare thenthen executedexecuted.. EachEach derivedderived classclass wouldwould thenthen havehave thethe opportunityopportunity toto initializeinitialize thatthat variable,variable, potentiallypotentially changingchanging it’sit’s value!value! ByBy restrictingrestricting thethe initializationinitialization ofof variablesvariables toto thethe constructorconstructor ofof thethe classclass thosethose variablesvariables belongbelong to,to, C++C++ ensuresensures thatthat allall variablesvariables areare initializedinitialized onlyonly onceonce. The end result is that the above example does not work because m_nValue was inherited from Base, and only non-inherited variables can be changed in the initialization list.

Page 92: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Constructors and initialization of derived classes

• When a derivedderived classclass isis destroyeddestroyed, eacheach destructordestructor isis calledcalled inin thethe reversereverse orderorder ofof constructionconstruction

92

class Base { public: int m_nValue; Base(int nValue=0) : m_nValue(nValue) { } };

class Derived: public Base : public Base { public: double m_dValue; Derived(double dValue=0.0, int nValue=0) // Call Base(// Call Base(intint) constructor with value ) constructor with value nValuenValue!!

: Base(: Base(nValuenValue)), m_dValue(dValue)

{ } };

Page 93: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance and access specifiers

93

class Base { public: // can be accessed by anybody// can be accessed by anybody int m_nPublic; private: // can only be accessed by Base member functions (but not derived classes)// can only be accessed by Base member functions (but not derived classes) int m_nPrivate; protected: // can be accessed by Base member functions, or derived classes// can be accessed by Base member functions, or derived classes int m_nProtected; };

class Derived: public Base : public Base { public: Derived() { m_nPublicm_nPublic = 1; // allowed: can access public base members from derived class// allowed: can access public base members from derived class m_nPrivatem_nPrivate = 2; // not allowed: can not access private base members from derived class// not allowed: can not access private base members from derived class m_nProtectedm_nProtected = 3; // allowed: can access protected base members from derived class// allowed: can access protected base members from derived class } };

Page 94: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance and access specifiers

94

class Base { public: // can be accessed by anybody// can be accessed by anybody int m_nPublic; private: // can only be accessed by Base member functions (but not derived classes)// can only be accessed by Base member functions (but not derived classes) int m_nPrivate; protected: // can be accessed by Base member functions, or derived classes// can be accessed by Base member functions, or derived classes int m_nProtected; };

class Derived: public Base : public Base { public: Derived() { m_nPublicm_nPublic = 1; // allowed: can access public base members from derived class// allowed: can access public base members from derived class m_nPrivatem_nPrivate = 2; // not allowed: can not access private base members from derived class// not allowed: can not access private base members from derived class m_nProtectedm_nProtected = 3; // allowed: can access protected base members from derived class// allowed: can access protected base members from derived class } };

int main() { Base cBase; cBase.m_nPublicm_nPublic = 1; // allowed// allowed cBase.m_nPrivatem_nPrivate = 2; // not allowed// not allowed cBase.m_nProtectedm_nProtected = 3; // not allowed// not allowed }

Page 95: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance and access specifiers

95

// A class can always access it’s own members regardless of access // A class can always access it’s own members regardless of access specifierspecifier // Inherit from Base publicly// Inherit from Base publicly class Pub: public Base: public Base { }; // Inherit from Base privately// Inherit from Base privately class Pri: private Base: private Base { }; // Inherit from Base // Inherit from Base protectedlyprotectedly class Pro: protected Base: protected Base { }; class Def: Base : Base // Defaults to private inheritance// Defaults to private inheritance { };

Page 96: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

public access specifiers

96

class Base { public: int m_nPublic; private: int m_nPrivate; protected: int m_nProtected; }; // Public inheritance means:// Public inheritance means: // // m_nPublicm_nPublic stays publicstays public // // m_nPrivatem_nPrivate stays privatestays private // // m_nProtectedm_nProtected stays protectedstays protected class Pub: public Base { Pub() { m_nPublicm_nPublic = 1; // ok: anybody can access public members// ok: anybody can access public members m_nPrivatem_nPrivate = 2; // Error : derived classes can't access private members in the base class!// Error : derived classes can't access private members in the base class! m_nProtectedm_nProtected = 3; // ok: derived classes can access protected members// ok: derived classes can access protected members } };

public inheritance is also the easiest to understand. When you inherit a base class publicly, all members keep their original access specifications int main(){ Pub cPub; cPub.m_nPublicm_nPublic = 1; // ok// ok cPub.m_nPrivatem_nPrivate = 2; // error// error cPub.m_nProtectedm_nProtected = 3; // error// error }

Page 97: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

private access specifiers

97

class Base { public: int m_nPublic; private: int m_nPrivate; protected: int m_nProtected; }; // Private inheritance means:// Private inheritance means: // // m_nPublicm_nPublic becomes privatebecomes private // // m_nProtectedm_nProtected becomes privatebecomes private

class Pri : private Base : private Base { Pri() { m_nPublicm_nPublic = 1; // ok: anybody can access public members// ok: anybody can access public members m_nPrivatem_nPrivate = 2; // Error : derived classes can't access private members in the base class!// Error : derived classes can't access private members in the base class! m_nProtectedm_nProtected = 3; // ok: derived classes can access protected members// ok: derived classes can access protected members } };

With private inheritance, all members from the base class are inherited as private. This means private members stay private, and protected and public members become private int main(){ Pri cPri; cPri.m_nPublic = 1; // error// error cPri.m_nPrivate = 2; // error// error cPri.m_nProtected = 3; // error// error }

Page 98: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

protected access specifiers

98

class Base { public: int m_nPublic; private: int m_nPrivate; protected: int m_nProtected; }; // protected inheritance means:// protected inheritance means: // // m_nPublicm_nPublic becomes protected becomes protected // // m_nProtectedm_nProtected becomes protected becomes protected class Pro : protected Base : protected Base { Pro() { m_nPublicm_nPublic = 1; // ok: anybody can access public members// ok: anybody can access public members m_nPrivatem_nPrivate = 2; // Error : derived classes can't access private members in the base class!// Error : derived classes can't access private members in the base class! m_nProtectedm_nProtected = 3; // ok: derived classes can access protected members// ok: derived classes can access protected members } };

With protected inheritance, the public and protected members become protected, and private members stay private int main(){ Pro cPro; cPro.m_nPublicm_nPublic = 1; // error// error cPro.m_nPrivatem_nPrivate = 2; // error// error cPro.m_nProtectedm_nProtected = 3; // error// error }

Page 99: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Adding members in a derived class

99

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { } void Identify() { cout << "I am a Base"; } };

class Derived: public Base : public Base { public: Derived(int nValue) :Base(nValue) { } int GetValue() { return m_nValue; } // Adding function member// Adding function member };

Derived cDerivedcDerived(5); cout << cDerived.GetValue(); // // 55 Base cBasecBase(5); cout << cBase.GetValueGetValue(); // Error// Error cBase.Identify(); // I am a Base// I am a Base cDerived.Identify(); // I am a Base// I am a Base

Page 100: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Redefining functionality in a derived class

100

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { } void Identify() { cout << "I am a Base "; } };

class Derived: public Base: public Base { public: Derived(int nValue) :Base(nValue) { } int GetValue() { return m_nValue; } // Adding function member// Adding function member // Here's our modified function// Here's our modified function void Identify() { cout << "I am a Derived"; } };

Derived cDerived(5); Base cBase(5); cBase.IdentifyIdentify(); // I am a Base cDerived.IdentifyIdentify(); // I am a Derived

Page 101: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Adding to existing functionality in a derived class

101

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { } void Identify() { cout << "I am a Base "; } };

class Derived: public Base: public Base { public: Derived(int nValue) :Base(nValue) { } int GetValue() { return m_nValue; } // Adding function member// Adding function member // Here's our modified function// Here's our modified function void Identify() {

Base::Identify()Base::Identify(); // if one write Identify(); then an infinite loop! // if one write Identify(); then an infinite loop! cout << "I am a Derived"; } };

Derived cDerived(5); Base cBase(5); cBase.IdentifyIdentify(); // I am a Base// I am a Base cDerived.IdentifyIdentify(); // I am a Base I am a Derived// I am a Base I am a Derived

Page 102: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Hiding existing functionality in a derived class

102

class Base { public: Base(int nValue) : m_nValue(nValue) { } int m_nValue; protected: void PrintValue() { cout << m_nValue; } }; class Derived: public Base: public Base {

Base::Base::m_nValuem_nValue;; public: Derived(int nValue) : Base(nValue) { } // Base::// Base::PrintValuePrintValue was inherited as protected, so the public has no accesswas inherited as protected, so the public has no access // But we're changing it to public by declaring it in the public section// But we're changing it to public by declaring it in the public section

Base::Base::PrintValuePrintValue;; };

Derived cDerived(7); /* The following won't work because /* The following won't work because m_nValuem_nValue has been redefined as private */has been redefined as private */ cout << cDerived.m_nValuem_nValue; // error// error // // PrintValuePrintValue is public in Derived, so this is okis public in Derived, so this is ok cDerived.PrintValuePrintValue(); // prints // prints 77

Page 103: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Multiple inheritance

103

class Scanner { }; class Printer { };

class Copier: public Scanner, public Printer: public Scanner, public Printer { };

Page 104: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Problems with multiple inheritance

104

class USBDevice { long m_lID; public: USBDevice(long lID) : m_lID(lID) { } long GetID() { return m_lID; } }; class NetworkDevice { long m_lID; public: NetworkDevice(long lID) : m_lID(lID) { } long GetID() { return m_lID; } }; class WirelessAdaptor: public : public USBDeviceUSBDevice, public , public NetworkDeviceNetworkDevice { public: WirelessAdaptor(long lUSBID, long lNetworkID) : USBDeviceUSBDevice((lUSBIDlUSBID), ), NetworkDeviceNetworkDevice((lNetworkIDlNetworkID)) { } };

WirelessAdaptor c54G(5442, 181742); cout << c54G.GetIDGetID(); // Which // Which GetIDGetID() do we call?() do we call? /* this function call is ambiguous, and you will receive /* this function call is ambiguous, and you will receive a compiler error if you try to compile it */a compiler error if you try to compile it */ cout << c54G.USBDevice::USBDevice::GetIDGetID();

Page 105: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

diamond problem

105

/* There are many issues that arise in this context, including whether Copier should /* There are many issues that arise in this context, including whether Copier should have one or two copies of have one or two copies of PoweredDevicePoweredDevice, and how to resolve certain types of , and how to resolve certain types of ambiguous references */ambiguous references */ class PoweredDevice { }; class Scanner: public PoweredDevice { }; class Printer: public PoweredDevice { }; class Copier: public Scanner, public Printer { };

Problem Problem : diamond problemdiamond problem

solutionsolution : virtual inheritancevirtual inheritance

Page 106: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

virtual inheritance

106

class PoweredDevicePoweredDevice { public: PoweredDevice(int nPower) { cout << "PoweredDevice: " << nPower << endl; } }; class ScannerScanner: public PoweredDevicePoweredDevice { public: Scanner(int nScanner, int nPower) : PoweredDevice(nPower) { cout << "Scanner: " << nScanner << endl; } }; class PrinterPrinter: public PoweredDevicePoweredDevice { public: Printer(int nPrinter, int nPower) : PoweredDevice(nPower) { cout << "Printer: " << nPrinter << endl; } }; class Copier: public Scanner, public Printer: public Scanner, public Printer { public: Copier(int nScanner, int nPrinter, int nPower) : Scanner(Scanner(nScannernScanner, , nPowernPower), Printer(), Printer(nPrinternPrinter, , nPowernPower)) { } };

Copier cCopier(1, 2, 3); PoweredDevice: 3 Scanner: 1 PoweredDevice: 3 Printer: 2

Scanner Printer

PoweredDevice PoweredDevice

Copier

PoweredDevice: 3 Scanner: 1 PoweredDevice: 3 Printer: 2

Page 107: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

virtual inheritance

107

class PoweredDevicePoweredDevice { public: PoweredDevice(int nPower) { cout << "PoweredDevice: " << nPower << endl; } };

class Scanner: virtual public virtual public PoweredDevicePoweredDevice { public: Scanner(int nScanner, int nPower) : PoweredDevice(nPower) { cout << "Scanner: " << nScanner << endl; } };

class Printer: virtual public virtual public PoweredDevicePoweredDevice { public: Printer(int nPrinter, int nPower) : PoweredDevice(nPower) { cout << "Printer: " << nPrinter << endl; } }; class Copier: public Scanner, public Printer : public Scanner, public Printer { public: // The Copier constructor is responsible for creating // The Copier constructor is responsible for creating PoweredDevicePoweredDevice Copier(int nScanner, int nPrinter, int nPower) : Scanner(nScanner, nPower), Printer(nPrinter, nPower), PoweredDevicePoweredDevice((nPowernPower) ) { } };

Copier cCopier(1, 2, 3); PoweredDevice: 3 Scanner: 1 PoweredDevice: 3 Printer: 2

Scanner Printer

PoweredDevice

Copier

PoweredDevice: 3 Scanner: 1 Printer: 2

Page 108: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

single inheritance

• Most of the problemsproblems that can be solved using multiplemultiple inheritanceinheritance can be solvedsolved using singlesingle inheritanceinheritance as well

•• ManyMany relativelyrelatively modernmodern languageslanguages such as Java and C# restrictsrestricts classesclasses toto singlesingle inheritanceinheritance of normal classes, but allow multiplemultiple inheritanceinheritance ofof interfaceinterface classesclasses (which we will talk about later)

108

Page 109: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Pointers and references to the base class of derived objects

109

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { } const char* GetName() { return "Base"; } int GetValue() { return m_nValue; } }; class Derived: : public Base public Base { public: Derived(int nValue) : Base(nValue) { } const char* GetName() { return "Derived"; } int GetValueDoubled() { return m_nValue * 2; } };

Derived cDerived(5); cout << "cDerived is a " << cDerived.GetName() << " and has value " << cDerived.GetValue() << endl; Derived &Derived &rDerived = cDerived; cout << "rDerived is a " << rDerived.GetName.GetName() << " and has value " << rDerived.GetValue.GetValue() << endl; Derived *Derived *pDerived = &cDerived; cout << "pDerived is a “ << pDerived-->>GetNameGetName() << " and has value “ << pDerived-->>GetValueGetValue() () << endl;

cDerived is a Derived and has value 5 rDerived is a Derived and has value 5 pDerived is a Derived and has value 5

Page 110: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Pointers and references to the base class of derived objects

110

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { } const char* GetName() { return "Base"; } int GetValue() { return m_nValue; } }; class Derived: public Base : public Base { public: Derived(int nValue) : Base(nValue) { } const char* GetName() { return "Derived"; } int GetValueDoubled() { return m_nValue * 2; } };

Derived cDerived(5); // These are both legal!// These are both legal! Base &Base &rBase = cDerived; Base *Base *pBase = &cDerived; cout << "cDerived is a “ << cDerived.GetName() << " and has value " << cDerived.GetValue() << endl; cout << "rBase is a " << rBase.GetName() << " and has value " << rBase.GetValue() << endl; cout << "pBase is a " << pBase->GetName() << " and has value " << pBase->GetValue() << endl;

cDerived is a Derived and has value 5

rBase is a BaseBase and has value 5

pBase is a BaseBase and has value 5

Page 111: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

virtual function

111

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { }

virtual virtual const char* const char* GetName() { return "Base"; } int GetValue() { return m_nValue; } }; class Derived: public Base { public: Derived(int nValue) : Base(nValue) { }

virtual virtual const char* const char* GetName(){return "Derived"; } int GetValueDoubled() { return m_nValue * 2; } };

Derived cDerived(5); // // These are both legal!These are both legal! Base &Base &rBase = cDerived; Base *Base *pBase = &cDerived; cout << "cDerived is a “ << cDerived.GetName() << " and has value " << cDerived.GetValue() << endl; cout << "rBase is a " << rBase.GetName() << " and has value " << rBase.GetValue() << endl; cout << "pBase is a " << pBase->GetName() << " and has value " << pBase->GetValue() << endl;

cDerived is a Derived and has value 5

rBase is a Derived Derived and has value 5

pBase is a Derived Derived and has value 5

Page 112: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

virtual function

112

class A { public: virtual const char* GetName() { return "A"; } }; class B: public A { public: virtual const char* GetName() { return "B"; } }; class C: public B { public: virtual const char* GetName() { return "C"; } }; class D: public C { public: virtual const char* GetName() { return "D"; } };

int main() { C cClass; A &rBase = cClass; cout << "rBase is a “ << rBase.GetName() << endl; return 0; }

rBase is a CC

Page 113: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Use of the virtual keyword

113

class Base { protected: int m_nValue; public: Base(int nValue) : m_nValue(nValue) { }

virtual const char* GetName() { return "Base"; } int GetValue() { return m_nValue; } }; class Derived: public Base { public: Derived(int nValue) : Base(nValue) { } // note lack of virtual keyword// note lack of virtual keyword const char* const char* GetNameGetName() { return "Derived"; }() { return "Derived"; } int GetValueDoubled() { return m_nValue * 2; } };

Exactly the same as if Derived::GetName() was explicitly tagged as virtual. Only the most base class function needs to be tagged as virtual for all of the derived functions to work virtually. However, having the keyword virtual on the derived functions does not hurt, and itit servesserves asas aa usefuluseful reminderreminder thatthat thethe functionfunction isis aa virtualvirtual functionfunction ratherrather thanthan aa normalnormal oneone. Consequently, it’s generally a good idea to use the virtual keyword for virtualized functions in derived classes even though it’s not strictly necessary

Page 114: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Return types of virtual functions

114

class Base { public:

virtualvirtual int GetValue() { return 5; } }; class Derived: public Base { public:

virtualvirtual double GetValue() { return 6.78; } };

Under normal circumstances, thethe returnreturn typetype ofof aa virtualvirtual functionfunction andand it’sit’s overrideoverride mustmust matchmatch.. Thus,Thus, thethe followingfollowing willwill notnot workwork

class Base { public:

virtualvirtual Base* GetThis() { return this; } }; class Derived: public Base { public:

virtualvirtual Derived* GetThis() { return this; } };

However, there is one special case in which this is not true.. IfIf thethe returnreturn typetype ofof aa virtualvirtual functionfunction isis aa pointerpointer oror aa referencereference toto aa class,class, overrideoverride functionsfunctions cancan returnreturn aa pointerpointer oror aa referencereference toto aa derivedderived classclass

• Note that some older compilers (eg. Visual Studio 6) do not support it

Page 115: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Example

115

class Animal { protected: string m_strName; Animal(string strName) : strName(strName) {} public: string GetName() { return m_strName; } virtual const char* virtual const char* Speak() { return "???"; } }; class Cat: public Animal { public: Cat(string strName) : Animal(strName) {} virtual const char* virtual const char* Speak() { return "Meow"; } }; class Dog: public Animal { public: Dog(string strName): Animal(strName) {} virtual const char* virtual const char* Speak() { return "Woof"; } };

We're makingmaking thisthis constructorconstructor protectedprotected becausebecause wewe don'tdon't wantwant peoplepeople creatingcreating AnimalAnimal objectsobjects directly,directly, but we still want derived classes to be able to use it

void Report(Animal &rAnimal) { cout << rAnimal.GetName() << " says " << rAnimal.Speak() << endl; } int main() { Cat cCat("Fred"); Dog cDog("Garbo"); Report(cCat); // Fred says Meow// Fred says Meow Report(cDog); // // GarboGarbo says Woofsays Woof }

Page 116: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Example

116

Cat acCats[] = { Cat("Fred"), Cat("Tyson"), Cat("Zeke") }; Dog acDogs[] = { Dog("Garbo"), Dog("Pooky"), Dog("Truffle") }; for (int i = 0; i < 3; i++) cout << acCats[i].GetName() << " says " << acCats[i].Speak() << endl; for (int I = 0; i < 3; i++) cout << acDogs[i].GetName() << " says " << acDogs[i].Speak() << endl;

Cat cFred("Fred"), cTyson("Tyson"), cZeke("Zeke"); Dog cGarbo("Garbo"), cPooky("Pooky"), cTruffle("Truffle"); // Set up an array of pointers to animals, and set those pointers to our Cat and Dog objects// Set up an array of pointers to animals, and set those pointers to our Cat and Dog objects Animal *apcAnimals[] = { &cFred, &cGarbo, &cPooky, &cTruffle, &cTyson, &cZeke }; for (int i = 0; i < 6; i++) cout << apcAnimals[i]->GetName() << " says " << apcAnimals[i]->Speak() << endl;

Page 117: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Virtual destructors

117

class Base { public: ~Base() { cout << "Calling ~Base()" << endl; } }; class Derived: public Base { int* m_pnArray; public: Derived(int nLength) { m_pnArray = new int[nLength]; } ~Derived() // note: not virtual// note: not virtual { cout << "Calling ~Derived()" << endl; delete[] m_pnArray; } };

Derived *pDerived = new Derived(5); Base *pBase = pDerived; delete pBase; // Calling ~Base()// Calling ~Base()

Page 118: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Virtual destructors

118

class Base { public:

virtual ~Base() { cout << "Calling ~Base()" << endl; } }; class Derived: public Base { int* m_pnArray; public: Derived(int nLength) { m_pnArray = new int[nLength]; }

virtual ~Derived() // note: virtual// note: virtual { cout << "Calling ~Derived()" << endl; delete[] m_pnArray; } };

Derived *pDerived = new Derived(5); Base *pBase = pDerived; delete pBase; // Calling ~Derived() // Calling ~Derived() // Calling ~Base()// Calling ~Base()

Page 119: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Overriding virtualization

119

// You probably won’t use this very often, but it’s good to know// You probably won’t use this very often, but it’s good to know class Base { public: virtual const char*virtual const char* GetName() { return "Base"; } }; class Derived: public Base { public virtual const char* virtual const char* GetName() { return "Derived"; } }; int main() { Derived cDerived; Base &rBase = cDerived; // Calls Base::GetName() instead of the virtualized Derived::GetName() cout << rBase.BaserBase.Base::::GetNameGetName() () << endl; }

Page 120: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Early binding • Binding refers to the process that is used toto convertconvert

identifiersidentifiers (such(such asas variablevariable andand functionfunction names)names) intointo machinemachine languagelanguage addressesaddresses. Although binding is used for both variables and functions, in this lesson we’re going to focus on function binding

•• EarlyEarly bindingbinding (also called staticstatic bindingbinding) meansmeans thethe compilercompiler isis ableable toto directlydirectly associateassociate thethe identifieridentifier namename (such(such asas aa functionfunction oror variablevariable name)name) withwith aa machinemachine addressaddress. Remember that all functions have a unique machine address. So when the compiler encounters a function call, it replaces the function call with a machine language instruction that tells the CPU to jump to the address of the function

120

Page 121: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Early binding

121

void PrintValue(int nValue) { cout << nValue; } int main() { PrintValuePrintValue((55)); // This is a direct function call// This is a direct function call return 0; }

Page 122: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Late Binding

•• late bindinglate binding or dynamic bindingdynamic binding

– function pointers

122

int Add(int nX, int nY) { return nX + nY; } int main() { // Create a function pointer and make it point to the Add function// Create a function pointer and make it point to the Add function intint (*(*pFcnpFcn)()(intint, , intint) = Add;) = Add; cout << pFcn(5, 3) << endl; // add // add 5 5 + + 33 return 0; }

Page 123: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The virtual table

• To implement virtual functions, C++ uses a special form of latelate bindingbinding knownknown asas thethe virtualvirtual tabletable

• The virtualvirtual tabletable isis aa lookuplookup tabletable ofof functionsfunctions used to resolveresolve functionfunction callscalls in a dynamic/late binding manner

– other names: vtablevtable,, virtualvirtual functionfunction table,table, virtualvirtual methodmethod table,table, dispatchdispatch tabletable

123

Page 124: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The virtual table class Baseclass Base { public: virtual void function1() {}; virtual void function2() {}; };

class Dclass D11: public Base: public Base { public: virtual void function1() {}; };

class Dclass D22: public Base: public Base { public: virtual void function2() {}; };

124

Page 125: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

The virtual table – D1 cClass; – Base *pClass = &cClass; – pClass->function1();

• Because cClass is a D1 object, cClass has it’s *__vptr set to the D1 virtual table

• Note that because pClass is a base pointer, it only points to the Base portion of cClass. However, also note that *__vptr is in the Base portion of the class, so pClass has access to this pointer. Finally, note that pClass->__vptr points to the D1 virtual table! Consequently, even though pClass is of type Base, it still has access to D1′s virtual table

• First, the program recognizes that function1() is a virtual function. Second, uses pClass->__vptr to get to D1′s virtual table. Third, it looks up which version of function1() to call in D1′s virtual table. This has been set to D1::function1(). Therefore, pClass->function1() resolves to D1::function1()!

125

Page 126: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Pure virtual (abstract) functions

• C++ allows you to create a special kind of virtual function called a purepure virtualvirtual functionfunction (or(or abstractabstract function)function) thatthat hashas nono bodybody atat all!all! A pure virtual function simply actsacts asas aa placeholderplaceholder thatthat isis meantmeant toto bebe redefinedredefined byby derivedderived classesclasses

• When we add a pure virtual function to our class, we are effectively saying, “itit isis upup toto thethe derivedderived classesclasses toto implementimplement thisthis functionfunction”

126

Page 127: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Abstract classes

• Using a pure virtual function has two main consequences:

– First, any class with oneone oror moremore purepure virtualvirtual functionsfunctions becomesbecomes anan abstractabstract basebase classclass, which means that itit cancan notnot bebe instantiated!instantiated!

– Second, anyany derivedderived classclass mustmust definedefine aa bodybody forfor thisthis function,function, oror thatthat derivedderived classclass willwill bebe consideredconsidered anan abstractabstract basebase classclass asas wellwell

127

Page 128: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Abstract class

128

class Base { public: // a normal non// a normal non--virtual functionvirtual function const char* SayHi() { return "Hi"; } // a normal virtual function// a normal virtual function virtual const char* GetName() { return "Base"; } // a pure virtual function// a pure virtual function

virtual int GetValue() = = 00;

}; int main() { Base cBase; // Error// Error cBase.GetValue(); // what would this do?// what would this do? }

Page 129: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Abstract class

129

class Animal { protected: string m_strName; Animal(string strName) : m_strName(strName) {} public: string GetName() { return m_strName; } virtual const char* virtual const char* Speak() { return "???"; } }; class Cow: public Animal class Cow: public Animal { public: Cow(std::string strName): Animal(strName) { } // We forgot to redefine Speak// We forgot to redefine Speak };

class Animal { …

virtual const char* virtual const char* Speak() = = 00;

};

Page 130: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Interface classes

• An interfaceinterface classclass is a class that hashas nono membersmembers variables,variables, andand wherewhere allall ofof thethe functionsfunctions areare purepure virtual!virtual! In other words, the class is purely a definition, and has no actual implementation –– virtualvirtual destructordestructor oror purepure virtualvirtual functionsfunctions

• Interfaces are useful when you wantwant toto definedefine

thethe functionalityfunctionality thatthat derivedderived classesclasses mustmust implement,implement, butbut leaveleave thethe detailsdetails ofof howhow thethe derivedderived classclass implementsimplements thatthat functionalityfunctionality entirelyentirely upup toto thethe derivedderived classclass –– classclass DclassDclass :: publicpublic BclassBclass,, publicpublic InterfaceInterface11,, publicpublic

InterfaceInterface22,, ……

130

Page 131: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Interface classes

131

class class IErrorLogIErrorLog { virtual bool OpenLog(const char *strFilename) = = 00; virtual bool CloseLog() = = 00; virtual bool WriteError(const char *strErrorMessage) = = 00; }; class FileErrorLog : IErrorLogIErrorLog { // implementation of // implementation of IErrorLogIErrorLog } class ScreenErrorLog: IErrorLogIErrorLog { // implementation of // implementation of IErrorLogIErrorLog } double MySqrt(double dValue, ScreenErrorLog &cLog) { /*…*//*…*/ } double MySqrt(double dValue, FileErrorLog &cLog) { /*…*//*…*/ } double MySqrt(double dValue, IErrorLogIErrorLog &&cLog) { /*…*//*…*/} See Example of slide #115

Page 132: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Composition Instead Of Inheritance

•• IsIs--AA vs HasHas--aa

132

class MouthMouth { public: void eat(Food bite); };

// // A person is a mouthA person is a mouth class Person: public Mouth class Person: public Mouth { };

// A person has a mouth// A person has a mouth class PersonPerson { public: void eat(Food bite) { itsMouth.eat(bite);itsMouth.eat(bite); } private:private: Mouth Mouth itsMouthitsMouth;; };

Page 133: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Inheritance and static member functions

• static member act the same as non-static member: – They inherit into the derived class

– If you redefine a static member, all the other overloaded functions in the base class are hidden

– If you change the signature of a function in the base class, all the base class versions with that function name are hidden (this is really a variation of the previous point)

• However, staticstatic member functions cannot be virtualvirtual

133

Page 134: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Function templates - overview

134

int getMax(int nX, int nY) { return (nX > nY) ? nX : nY; } double getMax(double dX, double dY) { return (dX > dY) ? dX : dY; } // …// …

Page 135: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Function templates - overview

135

// this is the template parameter declaration// this is the template parameter declaration

templatetemplate <typenametypename TypeType> // templatetemplate <class Typeclass Type> TypeType getMax(TypeType dX, TypeType dY) { return (dX > dY) ? dX : dY; } // …// … intint nValue = getMaxgetMax((33, , 77); ); // returns // returns 77 doubledouble dValue = getMaxgetMax((66..3434, , 1818..523523);); // returns // returns 1818..523523 charchar chValue = getMaxgetMax('a', '('a', '66');'); // returns 'a'// returns 'a'

intint n2 = getMaxgetMax<<intint>(>(33, , 77); ); // returns // returns 77

doubledouble d2 = getMaxgetMax<<intint>(>(66..3434, , 1818..523523);); // returns // returns 1818

Page 136: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Function templates - overview

136

// this is the template parameter declaration// this is the template parameter declaration // template <class T, class U>// template <class T, class U> templatetemplate <typenametypename T, T, typenametypename UU>

TT max(TT dX, UU dY)

{ return (dX > dY) ? dX : dY; } // …// … intint nValue = max(max(33, , 77); ); // returns // returns 77 doubledouble dValue = max(max(66..3434, , 1818..523523);); // returns // returns 1818..523523 charchar chValue = max('a', 'max('a', '66');'); // returns 'a'// returns 'a'

Page 137: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Function templates - overview

137

templatetemplate <typenametypename TypeType> TypeType getMax(TypeType dX, TypeType dY) { return (dX > dY) ? dX : dY; } class Cents { private: int m_nCents; public: Cents(int nCents) : m_nCents(nCents) { } };

Cents cNickle(5); Cents cDime(10); Cents cBigger = getMaxgetMax(cNickle, cDime); /* C++ will create a template /* C++ will create a template instance for max() that looks instance for max() that looks like this: */like this: */ Cents max(Cents tX, Cents tY) { return (tX > tY) ? tX : tY; }

Page 138: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Function templates - Exercise

138

templatetemplate <classclass T> T Average(T *atArray, int nNumValues) { T tSum = 0; for (int nCount=0; nCount < nNumValues; nCount++) tSum += atArray[nCount]; tSum /= nNumValues; return tSum; }

Cents cArray[] = { Cents(5), Cents(10), Cents(15), Cents(14) }; cout << Average(Average(cArraycArray, , 44)) << endl;

Write Cents Class?Write Cents Class?

Page 139: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Templates classes

139

templatetemplate <typenametypename T> // template <class T>// template <class T> class Array { int m_nLength;

T *T *m_ptData; public: Array() { m_nLength = 0; m_ptData = 0; } Array(int nLength) {

m_ptData= new Tnew T[nLength]; m_nLength = nLength; } ~Array(){ delete[] m_ptData; }

T&T& operator[](int nIndex) { assert(nIndex >= 0 && nIndex < m_nLength); return m_ptData[nIndex]; } int GetLength(); }; templatetemplate <typenametypename T> int Array<T>::Array<T>::GetLengthGetLength() () { return m_nLength; }

int main() {

Array<Array<intint> > anArray(12);

Array<double>Array<double> adArray(12); for (int n = 0; n < 12; n++) { anArray[n] = n; adArray[n] = n+ 0.5; } return 0; }

Page 140: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Expression parameters

• A templatetemplate expressionexpression parameterparameter isis aa parameterparameter thatthat doesdoes notnot substitutesubstitute forfor aa typetype, but is instead replaced by a value

• An expression parameter can be any of the following: – A value that has an integral type or enumerationintegral type or enumeration

–– AA pointerpointer oror referencereference toto anan objectobject

–– AA pointerpointer oror referencereference toto aa functionfunction

–– AA pointerpointer oror referencereference toto aa classclass membermember functionfunction

140

Page 141: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Expression parameters

141

// // nSizenSize is the expression parameteris the expression parameter template template <typenametypename T, intint nSizenSize> class Buffer { // The expression parameter controls the size of the array// The expression parameter controls the size of the array

T m_atBuffer[nSizenSize]; public:

T*T* GetBuffer() { return m_atBuffer; }

T&T& operator[](int nIndex) {

return m_atBuffer[nIndex]; } }; // declare an integer buffer with room for // declare an integer buffer with room for 12 12 charschars

Buffer<Buffer<intint, , 1212> > cIntBuffer; // declare a char buffer with room for // declare a char buffer with room for 31 31 charschars Buffer<char, Buffer<char, 3131> > cCharBuffer;

Page 142: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Expression parameters

142

templatetemplate <classclass T, intint N> class mysequencemysequence { T memblock [N]; public: void setmember (int x, T value); }; templatetemplate <classclass T, intint N> void mysequencemysequence<T,N><T,N>::::setmember (int x, T value) { memblock[x]=value; }

Page 143: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Expression parameters

143

/*/* AnAn expressionexpression parameterparameter cancan bebe anyany ofof thethe followingfollowing:: AA valuevalue thatthat hashas anan integralintegral typetype …… */*/

template <typename T, floatfloat nSize>

class C{ };

template <typename T, double double nSize>

class C{ };

Page 144: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Template specialization

144

template <typename T> class Storage { T m_tValue; public: Storage(T tValue) { m_tValue = tValue; } ~Storage() { } void Print() { cout << m_tValue; } };

Storage<Storage<intint> > nValue(5); Storage<double> Storage<double> dValue(6.7); nValue.Print(); // ok// ok dValue.Print(); // ok// ok // but !!!// but !!! char *strString = new char[40]; cin >> strString; Storage<char*>Storage<char*> strValue(strString); delete delete strStringstrString;; // Print out our value// Print out our value // This will print garbage// This will print garbage strValue.Print(); // fix it using template specialization // fix it using template specialization

Page 145: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Template specialization - member functions

145

template <typename T> class Storage { T m_tValue; public: Storage(T tValue) { m_tValue = tValue; } ~Storage() {} void Print(){ cout << m_tValue;} }; Storage<char*char*>::Storage(char* tValue) { m_tValue = new char[strlen(tValue)+1]; strcpy(m_tValue, tValue); } Storage<char*char*>::~Storage() { delete[] m_tValue; }

specialization for char *specialization for char *

Page 146: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class template specialization

146

template <typename T> class Storage8 { T m_tType[8]; public: void Set(int nIndex, const T & tType) { m_tType[nIndex] = tType; } const T& Get(int nIndex) { return m_tType[nIndex]; } };

// Define a Storage// Define a Storage8 8 for integersfor integers Storage8<int> cIntStorage; // Define a Storage// Define a Storage8 8 for for boolbool Storage8<bool> cBoolStorage;

it’sit’s possiblepossible toto compresscompress allall 88 boolsbools intointo aa singlesingle byte,byte, eliminatingeliminating thethe wastedwasted spacespace altogetheraltogether

Page 147: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Class template specialization

147

template <typename T> class Storage8 { T m_tType[8]; /* … *//* … */ }; // the following is a template class with no // the following is a template class with no templatedtemplated parametersparameters template <>template <> class StorageStorage88<<boolbool>> // we're specializing Storage// we're specializing Storage8 8 for for boolbool { unsigned char m_tType; public: void Set(int nIndex, bool tType) { unsigned char nMask = 1 << nIndex; if (tType) m_tType |= nMask; else m_tType &= ~nMask; } bool Get(int nIndex) { unsigned char nMask = 1 << nIndex; return m_tType & nMask; } };

Page 148: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Partial template specialization

148

// // nSizenSize is the expression parameteris the expression parameter template template <typenametypename T, intint nSizenSize> class Buffer { // The expression parameter controls the size of the array// The expression parameter controls the size of the array

T m_atBuffer[nSizenSize];

public:

T*T* GetBuffer() { return m_atBuffer; }

T&T& operator[](int nIndex) {

return m_atBuffer[nIndex]; } }; template template <typenametypename T, intint nSizenSize> void PrintBufferString(Buffer<T, Buffer<T, nSizenSize> &> &rcBuf) { std::cout << rcBuf.GetBuffer() << std::endl; }

Buffer<char, Buffer<char, 1010>> cChar10Buffer; strcpy(cChar10Buffer.GetBuffer(), "Ten");

PrintBufferString(cChar10Buffer); // Ten// Ten Buffer<Buffer<intint, , 1010> > cInt10Buffer; for (int n=0; n < 10; n++) cInt10Buffer[n] = n; // print the address of pointer// print the address of pointer PrintBufferStringPrintBufferString(cInt(cInt1010Buffer);Buffer);

ProblemProblem :: ensureensure thatthat onlyonly arraysarrays ofof typetype charchar cancan bebe passedpassed toto functionfunction

Page 149: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Partial template specialization

149

// Solution // Solution 11 void PrintBufferString(Buffer<char, Buffer<char, 1010> &> &rcBuf) { std::cout << rcBuf.GetBuffer() << std::endl; } // Problem of solution // Problem of solution 11 int main() { Buffer<char, Buffer<char, 1010>> cChar10Buffer; Buffer<char, Buffer<char, 1111> > cChar11Buffer; strcpy(cChar10Buffer.GetBuffer(), "Ten"); strcpy(cChar11Buffer.GetBuffer(), "Eleven"); PrintBufferString(cChar10Buffer); PrintBufferStringPrintBufferString(cChar(cChar1111Buffer)Buffer); // this will not compile// this will not compile return 0; }

Page 150: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Partial template specialization

150

// Solve problem of solution // Solve problem of solution 1 1 using using Partial template specializationPartial template specialization template<template<intint nSizenSize>> void PrintBufferString(Buffer<char, Buffer<char, nSizenSize> &> &rcBuf) { std::cout << rcBuf.GetBuffer() << std::endl; } int main() { Buffer<char, Buffer<char, 1010>> cChar10Buffer; Buffer<char, Buffer<char, 1111> > cChar11Buffer; strcpy(cChar10Buffer.GetBuffer(), "Ten"); strcpy(cChar11Buffer.GetBuffer(), "Eleven"); PrintBufferString(cChar10Buffer); // Ok// Ok PrintBufferStringPrintBufferString(cChar(cChar1111Buffer)Buffer); // Ok// Ok return 0; }

Page 151: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling • provides a mechanismmechanism to decoupledecouple handlinghandling ofof errorserrors or

other exceptional circumstances fromfrom thethe typicaltypical controlcontrol flowflow ofof youryour codecode

• Exceptions in C++ are implemented using three keywords that work in conjunction with each other: throwthrow, trytry, and catchcatch

•• throwthrow statementstatement is used to signalsignal that an exception or error case has occurred –– throw throw --11;; // throw a literal integer value// throw a literal integer value –– throw ENUM_INVALID_INDEX;throw ENUM_INVALID_INDEX; // throw an // throw an enumenum valuevalue –– throw “Error throw “Error 1010"; "; // throw a char* or string// throw a char* or string –– throw throw dXdX; ; // throw a double variable that was previously defined// throw a double variable that was previously defined –– throw throw MyErrorMyError("Fatal Error"); ("Fatal Error"); // Throw an object of class // Throw an object of class MyErrorMyError

151

Page 152: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling

152

trytry {{ // Statements that may throw exceptions you want to handle// Statements that may throw exceptions you want to handle throw throw --11;; }} // Any exceptions of type // Any exceptions of type intint thrown within the above try blockthrown within the above try block catch (catch (intint)) { { cerr << "We caught an exception of type int" << endl; }} // Any exceptions of type double thrown within the above try block// Any exceptions of type double thrown within the above try block catch (double)catch (double) {{ cerr << "We caught an exception of type double" << endl; }}

Page 153: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling - Example

153

double MySqrt(double dX) { if (dX < 0.0) throwthrow "Can not take "Can not take sqrtsqrt of negative number"of negative number"; return sqrt(dX); } int main() { double dX = -60; try { cout << "The sqrt of " << dX << " is " << MySqrtMySqrt((dXdX)) << endl; } catch (char* strException) // catch exceptions of type char*// catch exceptions of type char* { cerr << "Error: " << strException << endl; } }

Page 154: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling - stack unwinding

154

void Last() { cout << "Start Last" << endl; cout << "4 throwing int"; throw throw --11;; cout << "End Last" << endl; } void Third(){ cout << "Start Third" << endl; Last();Last(); cout << "End Third" << endl; } void Second() { cout << "Start Second" << endl; try { Third();Third(); } catch(double)catch(double) { cerr << “2 caught double“; } cout << "End Second" << endl; }

void First() { cout << "Start First" << endl; try { Second(); Second(); } catch (catch (intint)) { cerr << "1 caught int\n"; } catch (double) catch (double) { cerr << "1 caught double\n"; } cout << "End First" << endl; } int main() { cout << "Start main" << endl; try { First();First(); } catch (catch (intint)) { cerr << "main caught int\n"; } cout << "End main" << endl; }

Start main Start First Start Second Start Third Start Last 4 throwing int 1 caught int End First End main

Page 155: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Catch-all handlers

• C++ provides us with a mechanism to catch all types of exceptions

– it should be placed last in the catch block be placed last in the catch block chain

155

trytry { throw 5; // throw an // throw an intint exceptionexception } catch (double catch (double dXdX){){ cout << "caught an exception of type double: " << dX << endl; } catch (...) {catch (...) {// catch// catch--all handlerall handler cout << “caught an exception of an undetermined type" << endl; }

Page 156: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling - Example

156

double MySqrt(double dX) { if (dX < 0.0) throwthrow "Can not take "Can not take sqrtsqrt of negative number"of negative number"; return sqrt(dX); } int main() { double dX = -60; cout << "The sqrt of " << dX << " is " << MySqrtMySqrt((dXdX)) << endl; } /*main/*main terminatesterminates withwith anan unhandledunhandled exception,exception, thethe OSOS willwill generallygenerally notifynotify youyou thatthat anan unhandledunhandled exceptionexception errorerror hashas occurredoccurred */*/ int main(){ trytry { // program// program } catch(...)catch(...) { cerr << "Abnormal termination" << endl; } return 1; }

Page 157: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception specifiers • a mechanism that allows us to use a functionfunction declarationdeclaration

toto specifyspecify whetherwhether aa functionfunction maymay oror willwill notnot throwthrow exceptionsexceptions. This can be useful in determining whether a function call needs to be put inside a try block or not – an empty throw statement to denote that a function does not

throw any exceptions outside of itself • int DoSomething() throw()throw(); //// doesdoes notnot throwthrow exceptionsexceptions

– a specific throw statement to denote that a function may throw a particular type of exception

• int DoSomething() throw(double)throw(double); //// maymay throwthrow aa doubledouble

– a catch-all throw statement to denote that a function may throw an unspecified type of exception

• int DoSomething() throw(throw(......)); //// maymay throwthrow anythinganything

• exception specifies are rarely used in practice, are not well

supported by compilers

157

Page 158: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

std::exception

• The C++ standard library comes with an exception class that is used by many of the other standard library classes.

158

class exception { public: /* … */ virtual const char* what() what() const throw(); }

Page 159: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception classes

159

#include <exception>#include <exception> class myExceptionmyException: public exception : public exception { virtual const char* what() const throw() { return "My exception happened"; } } ; int main () { try { /* ... */ throw throw myExceptionmyException();(); } catch (exception&exception& e) { cout << e.what() << endl; } return 0; }

Page 160: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception dangers and downsides

• What happens if WriteFile() fails

160

try { OpenFile(strFilename); WriteFileWriteFile((strFilenamestrFilename, , strDatastrData);); CloseFile(strFilename); } catch (FileExceptionFileException &&cExceptioncException) { cerr << "Failed to write to file: " << cException.what() << endl; }

Page 161: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception dangers and downsides

161

try { OpenFile(strFilename); WriteFileWriteFile((strFilenamestrFilename, , strDatastrData);); CloseFile(strFilename); } catch (FileExceptionFileException &&cExceptioncException) { CloseFileCloseFile((strFilenamestrFilename);); cerr << "Failed to write to file: " << cException.what() << endl; }

Page 162: C++ Programming Languagesce.sharif.edu/courses/94-95/1/ce244-2/resources/root/...Outline •object-oriented programming –Classes and class members –Access functions and encapsulation

Exception handling - example

162

try { int * myarray= new int[1000]; } catch (bad_allocbad_alloc&&) { cout << "Error allocating memory." << endl; }