1 const and this ying wu electrical engineering & computer science northwestern university...

36
1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University [email protected] EECS 230 Lectures Series

Upload: wilfrid-gilmore

Post on 17-Jan-2016

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

1

const and this

Ying Wu Electrical Engineering & Computer

ScienceNorthwestern [email protected]

EECS 230 Lectures Series

Page 2: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

2

A Brief Review of Last Week

What motivate the concepts of class and object? How to construct a class? How is encapsulation embedded in class? How to separate interface and implementation? Why do we need public and private? What is the difference between public and private?

Why do we need constructors/destructors? When constructors and destructors are called? How to assign an object to another object?

(problem? ) How to pass an object to a function?

Page 3: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

3

Some perspectives Special topics

– const– The this pointer– static– Dynamic memory allocation– Classes with pointer data members

(!!!)– Operator overloading

Advanced topics– Inheritance– (*) Virtual functions and polymorphism

Page 4: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

4

What to learn today?

const– const variables– const pointers– const objects– const data members– const member functions

this– The motivation– The usage

Page 5: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

5

const Qualifier const qualifier

– Variable cannot be changed– Attempting to change a const variable leads to a compiler

error (i.e., the complier will catch it for you!) Why do we need const?

– We know exactly what will never change in the scope– Use it when function does not need to change a variable– Reduce the possible bugs by taking advantage of the

complier– Especially, it is useful when we pass pointers and

references

void printArray(const int* a, const int size)

{

for(int k=0;k<size;k++)

cout << a[k];

}

Page 6: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

6

const pointer

FOUR types– Non-constant pointer to non-constant

data– Constant pointer to non-constant

data– Non-constant pointer to constant

data– Constant pointer to constant data

Page 7: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

7

Non-const ptr to non-const data

The pointer can change and points to other data The data can change through the pointer e.g.

int a = 5;

int *ptr = &a;

ptr

00100060

a

5

&a00100060

ptr

00100060

a

8

&a00100060a = 8;

(or *ptr = 8)

ptr

00100068

a

5

&b00100068

b

6

int b = 6;

ptr = &b;

Page 8: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

8

Non-const ptr to const data

The pointer can change to point to other data The data can NOT be modified through this pointer

int a = 5;

const int * ptr = &a;

ptr

00100060

a

5

&a00100060

int b = 6;

ptr = &b;

ptr

00100068

a

5

&b00100068

b

6

*ptr = 8ptr

00100068

b

8

&b00100068

But b = 8 is OK

Page 9: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

9

const ptr to non-const data

The pointer always points to the same memory location

The data at the location can change through the pointerint a = 5;

int * const ptr = &a;

a = 8;

(or *ptr = 8)

ptr

00100060

a

5

&a00100060

ptr

00100060

a

8

&a00100060

int b = 6;

ptr = &b;

ptr

00100068

a

5

&b00100068

b

6

Page 10: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

10

const ptr to const data The pointer always points to the same memory location The data at the location can NOT be changed through

the pointer

int a = 5;

const int * const ptr = &a;

ptr

00100060

a

5

&a00100060

*ptr = 8 ptr

00100060

a

8

&a00100060

int b = 6;

ptr = &b;

ptr

00100068

a

5

&b00100068

b

6

Page 11: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

11

How to read and remember?

const int x;

const int *ptr;

int * const ptr;

const int * const ptr;

“x is an integer constant”

“ptr is a const pointer to an integer”

“ptr is a pointer to an integer constant”

“ptr is a constant pointer to an integer constant”

Page 12: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

12

const Objects Principle of least privilege

– Only give objects permissions they need, no more

Keyword const– Specify that an object is not modifiable– Any attempt to modify the object generates

a syntax error by the compiler– Example

const CVariable pi(“pi”, 3.1415926); Declares a const object pi of class CVariable

and initializes it.

Page 13: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

13

const Member Functions const objects require const functions!!

– Member functions declared const cannot modify their object

– const must be specified in function prototype and definition

– Prototype:ReturnType FunctionName(param1,param2…) const;

– Definition:ReturnType FunctionName(param1,param2…) const { …}

– Example: double CVariable::Value() const

{

return m_dValue;

};Returns the value of a data member but doesn’t modify

anything so is declared const

Page 14: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

14

Question?

Can constructor/destructor a const member function?

• NO!–They need to initialize variables, therefore modifying them

Page 15: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

15

const Member Functions

Things to pay more attention!– const objects require const

functions– Non-const functions can not use

const objects, even if they do not change the object

Page 16: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

16

1 // Fig. 7.1: time5.h

2 // Declaration of the class Time.

3 // Member functions defined in time5.cpp

4 #ifndef TIME5_H

5 #define TIME5_H

6

7 class Time {

8 public:

9 Time( int = 0, int = 0, int = 0 ); // default constructor

10

11 // set functions

12 void setTime( int, int, int ); // set time

13 void setHour( int ); // set hour

14 void setMinute( int ); // set minute

15 void setSecond( int ); // set second

16

17 // get functions (normally declared const)

18 int getHour() const; // return hour

19 int getMinute() const; // return minute

20 int getSecond() const; // return second

21

22 // print functions (normally declared const)

23 void printMilitary() const; // print military time

24 void printStandard(); // print standard time

25 private:

26 int hour; // 0 - 23

27 int minute; // 0 - 59

28 int second; // 0 - 59

29 };

30

31 #endif

1. Class definition

1.1 Function prototypes

1.2 Member variables

Page 17: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

17

Source Code1. Load Header

1.1 Function definitions

32 // Fig. 7.1: time5.cpp33 // Member function definitions for Time class.34 #include <iostream>3536 using std::cout;3738 #include "time5.h"3940 // Constructor function to initialize private data.41 // Default values are 0 (see class definition).42 Time::Time( int hr, int min, int sec ) 43 { setTime( hr, min, sec ); }4445 // Set the values of hour, minute, and second.46 void Time::setTime( int h, int m, int s )47 {48 setHour( h );49 setMinute( m );50 setSecond( s );51 }5253 // Set the hour value54 void Time::setHour( int h ) 55 { hour = ( h >= 0 && h < 24 ) ? h : 0; }5657 // Set the minute value58 void Time::setMinute( int m ) 59 { minute = ( m >= 0 && m < 60 ) ? m : 0; }6061 // Set the second value62 void Time::setSecond( int s )63 { second = ( s >= 0 && s < 60 ) ? s : 0; }

The constructor is non-const but it can be called for const objects.

Page 18: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

18

1.1 Function definitions

1.2 Purposely leave out const

keyword for printStandard

64

65 // Get the hour value

66 int Time::getHour() const { return hour; }

67

68 // Get the minute value

69 int Time::getMinute() const { return minute; }

70

71 // Get the second value

72 int Time::getSecond() const { return second; }

73

74 // Display military format time: HH:MM

75 void Time::printMilitary() const

76 {

77 cout << ( hour < 10 ? "0" : "" ) << hour << ":"

78 << ( minute < 10 ? "0" : "" ) << minute;

79 }

80

81 // Display standard format time: HH:MM:SS AM (or PM)

82 void Time::printStandard() // should be const

83 {

84 cout << ( ( hour == 12 ) ? 12 : hour % 12 ) << ":"

85 << ( minute < 10 ? "0" : "" ) << minute << ":"

86 << ( second < 10 ? "0" : "" ) << second

87 << ( hour < 12 ? " AM" : " PM" );

88 }

Keyword const in function definition and prototype.

Non-const functions cannot use const objects, even if they don’t modify them (such as printStandard).

Page 19: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

19

1. Initialize variables

2. Attempt to use non-const

functions with const objects

Program Output

89 // Fig. 7.1: fig07_01.cpp90 // Attempting to access a const object with91 // non-const member functions.92 #include "time5.h"9394 int main()95 {96 Time wakeUp( 6, 45, 0 ); // non-constant object97 const Time noon( 12, 0, 0 ); // constant object9899 // MEMBER FUNCTION OBJECT100 wakeUp.setHour( 18 ); // non-const non-const101102 noon.setHour( 12 ); // non-const const103104 wakeUp.getHour(); // const non-const105106 noon.getMinute(); // const const107 noon.printMilitary(); // const const108 noon.printStandard(); // non-const const109 return 0;110}

Compiling...Fig07_01.cppd:fig07_01.cpp(14) : error C2662: 'setHour' : cannot convert 'this' pointer from 'const class Time' to 'class Time &'Conversion loses qualifiersd:\fig07_01.cpp(20) : error C2662: 'printStandard' : cannot convert 'this' pointer from 'const class Time' to 'class Time &'Conversion loses qualifiersTime5.cppError executing cl.exe. test.exe - 2 error(s), 0 warning(s)

Compiler errors generated.

Page 20: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

20

const Data Member Member initializer syntax

– Data member increment in class Increment – constructor for Increment is modified as

follows:Increment::Increment( int c, int i ) : increment( i )

{ count = c; }

– All data members can be initialized using member initializer syntax

– consts and references must be initialized using member initializer syntax

– Multiple member initializers Use comma-separated list after the colon

Page 21: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

21

1. Class definition

1.1 Function definitions

1 // Fig. 7.2: fig07_02.cpp2 // Using a member initializer to initialize a3 // constant of a built-in data type.4 #include <iostream>56 using std::cout;7 using std::endl;89 class Increment {10 public:11 Increment( int c = 0, int i = 1 );12 void addIncrement() { count += increment; }13 void print() const;1415 private:16 int count;17 const int increment; // const data member18 };1920 // Constructor for class Increment21 Increment::Increment( int c, int i )22 : increment( i ) // initializer for const member23 { count = c; }2425 // Print the data26 void Increment::print() const27 {28 cout << "count = " << count29 << ", increment = " << increment << endl;30 }3132 int main()33 {

If we try to initialize increment with an assignment statement (such as increment = i ) instead of a member initializer we get an error.

Page 22: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

22

1.2 Initialize variables

2. Function calls

3. Output results

34 Increment value( 10, 5 );

35

36 cout << "Before incrementing: ";

37 value.print();

38

39 for ( int j = 0; j < 3; j++ ) {

40 value.addIncrement();

41 cout << "After increment " << j + 1 << ": ";

42 value.print();

43 }

44

45 return 0;

46 }

Before incrementing: count = 10, increment = 5After increment 1: count = 15, increment = 5After increment 2: count = 20, increment = 5After increment 3: count = 25, increment = 5

Page 23: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

23

Motivation for this

Inside the scope of a class, all the data members and member functions are accessible. They are local information

What is missed? It is like the situation where

many people are in a room. They know each other, but they don’t know where they are!

Objects should know their own address.

this

Page 24: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

24

Characteristics this pointer

– Allows objects to access their own address– It makes the member functions know each other implicitly– It is a pointer– Not part of the object itself – Implicit first argument on non-static member function call to

the object – Implicitly reference member data and functions – The type of the this pointer depends upon the type of the

object and whether the member function using this is constIn a non-const member function of Employee, this has type

Employee * const Constant pointer to an Employee object (what does it mean?)

In a const member function of Employee, this has typeconst Employee * const

Constant pointer to a constant Employee object (what does it mean?)

Page 25: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

25

Example

Examples using this– For a member function print data

member x, either this->x

or ( *this ).x

Page 26: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

26

1 // Fig. 7.7: fig07_07.cpp 2 // Using the this pointer to refer to object members.3 #include <iostream>45 using std::cout;6 using std::endl;78 class Test {9 public:10 Test( int = 0 ); // default constructor11 void print() const;12 private:13 int x;14 };1516 Test::Test( int a ) { x = a; } // constructor1718 void Test::print() const // ( ) around *this required19 {20 cout << " x = " << x21 << "\n this->x = " << this->x22 << "\n(*this).x = " << ( *this ).x << endl;23 }2425 int main()26 {27 Test testObject( 12 );2829 testObject.print();3031 return 0;32 }

1. Class definition

1.1 Function definition

1.2 Initialize object

2. Function call

Printing x directly.

Print x using the arrow -> operator off the this pointer.

Printing x using the dot (.) operator. Parenthesis required because dot operator has higher precedence than *. Without, interpreted incorrectly as *(this.x).

Page 27: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

27

Program Output

 

x = 12 this->x = 12(*this).x = 12

All three methods have the same result.

Page 28: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

28

So what?

Member functions will know each other through this

Cascaded member function calls– Function returns a reference pointer

to the same object { return *this; }

– Other functions can operate on that pointer

– Functions that do not return references must be called last

Page 29: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

29

Example: A = (b+1)*2 –3 ??Class CVar{

double m_dVar;

Public:

CVar(double v = 0) { m_dVar = v; };

~CVar() { }; // do nothing

void SetVar(const double v) { m_dVar = v; };

CVar& INC(double s) { m_dVar += s; return *this; };

CVar& DEC(double s) { m_dVar -= s; return *this; };

CVar& MUL(double s) { m_dVar *= s; return *this; };

};

// is it more professional?

// why can we do this?

void main()

{

CVar v(4.5);

v.INC(1).MUL(2).DEC(3);

}

// an old way

void main()

{

CVar v(4.5);

v.INC(1);

v.MUL(2);

v.DEC(3);

}

Page 30: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

30

Example Example of cascaded member function calls

– Member functions setHour, setMinute, and setSecond all return *this (reference to an object)

– For object t, considert.setHour(1).setMinute(2).setSecond(3);

– Executes t.setHour(1), returns *this (reference to object) and the expression becomes

t.setMinute(2).setSecond(3);

– Executes t.setMinute(2), returns reference and becomes

t.setSecond(3);

– Executes t.setSecond(3), returns reference and becomes

t;

– Has no effect

Page 31: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

31

1. Class definition

1 // Fig. 7.8: time6.h2 // Cascading member function calls.34 // Declaration of class Time.5 // Member functions defined in time6.cpp6 #ifndef TIME6_H7 #define TIME6_H89 class Time {10 public:11 Time( int = 0, int = 0, int = 0 ); // default constructor1213 // set functions14 Time &setTime( int, int, int ); // set hour, minute, second15 Time &setHour( int ); // set hour16 Time &setMinute( int ); // set minute17 Time &setSecond( int ); // set second1819 // get functions (normally declared const)20 int getHour() const; // return hour21 int getMinute() const; // return minute22 int getSecond() const; // return second2324 // print functions (normally declared const)25 void printMilitary() const; // print military time26 void printStandard() const; // print standard time27 private:28 int hour; // 0 - 2329 int minute; // 0 - 5930 int second; // 0 - 5931 };3233 #endif

Notice the Time & - function returns a reference to a Time object. Specify object in function definition.

TELL ME: why do we do that?

Page 32: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

32

1. Load header file

1.1 Function definitions

34 // Fig. 7.8: time.cpp

35 // Member function definitions for Time class.

36 #include <iostream>

37

38 using std::cout;

39

40 #include "time6.h"

41

42 // Constructor function to initialize private data.

43 // Calls member function setTime to set variables.

44 // Default values are 0 (see class definition).

45 Time::Time( int hr, int min, int sec )

46 { setTime( hr, min, sec ); }

47

48 // Set the values of hour, minute, and second.

49 Time &Time::setTime( int h, int m, int s )

50 {

51 setHour( h );

52 setMinute( m );

53 setSecond( s );

54 return *this; // enables cascading

55 }

56

57 // Set the hour value

58 Time &Time::setHour( int h )

59 {

60 hour = ( h >= 0 && h < 24 ) ? h : 0;

61

62 return *this; // enables cascading

63 }

64

Returning *this enables cascading function calls

Page 33: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

33

1.1 Function definitions

65 // Set the minute value

66 Time &Time::setMinute( int m )

67 {

68 minute = ( m >= 0 && m < 60 ) ? m : 0;

69

70 return *this; // enables cascading

71 }

72

73 // Set the second value

74 Time &Time::setSecond( int s )

75 {

76 second = ( s >= 0 && s < 60 ) ? s : 0;

77

78 return *this; // enables cascading

79 }

80

81 // Get the hour value

82 int Time::getHour() const { return hour; }

83

84 // Get the minute value

85 int Time::getMinute() const { return minute; }

86

87 // Get the second value

88 int Time::getSecond() const { return second; }

89

90 // Display military format time: HH:MM

91 void Time::printMilitary() const

92 {

93 cout << ( hour < 10 ? "0" : "" ) << hour << ":"

94 << ( minute < 10 ? "0" : "" ) << minute;

Returning *this enables cascading function calls

Page 34: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

34

1.1 Function definitions

--------------------------1. Load header

1.1 Initialize Time object

2. Function calls

3. Print values

95 }9697 // Display standard format time: HH:MM:SS AM (or PM)98 void Time::printStandard() const99 {100 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 ) 101 << ":" << ( minute < 10 ? "0" : "" ) << minute 102 << ":" << ( second < 10 ? "0" : "" ) << second103 << ( hour < 12 ? " AM" : " PM" );104}105// Fig. 7.8: fig07_08.cpp106// Cascading member function calls together107// with the this pointer108#include <iostream>109110using std::cout;111using std::endl;112113#include "time6.h"114115int main()116{117 Time t;118119 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 );120 cout << "Military time: ";121 t.printMilitary();122 cout << "\nStandard time: ";123 t.printStandard();124125 cout << "\n\nNew standard time: ";126 t.setTime( 20, 20, 20 ).printStandard();

Notice cascading function calls.

Cascading function calls. printStandard must be called after setTime because printStandard does not return a reference to an object.

t.printStandard().setTime(); would cause an error.

printStandard does not return a reference to an object.

Page 35: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

35

127 cout << endl;

128

129 return 0;

130}

Military time: 18:30Standard time: 6:30:22 PM New standard time: 8:20:20 PM

Page 36: 1 const and this Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series

36

Questions for today1. Will it work?

void myFunc(const int* a, const int size)

{

for(int k=0;k<size;k++){

a[k] ++;

cout << a[k];

}

}

2. What is wrong?double var = 3.1415926;

double * const ptr = &var;

double PI = 3.1415926;

ptr = &PI;

3. What is wrong and how to correct?double var = 3.1415926;

double *ptr = &var;

const double PI = 3.1415926;

ptr = &PI;