class7
DESCRIPTION
TRANSCRIPT
Const and the Copy Constructors
Object Oriented Paradigm
• Separating interface from implementation• Constructors & destructors• Public vs private
• Not C++ specific
Const – specific to C++
• const keyword• Ensures initialized value is its only value ever• Sometimes it’s a promise
Example
No call to Read/Write?
• No matching call to write(Point)?• We have function write(Point)!
• But wait…• Errors are on lines that contain P.reflectX()• Compiler sees write(Point&) as candidate, but
just won’t let you pass the result of P.refelctX() as a reference
Read Problem
• read() tries to change what is returned by P.reflectX()
• P.reflectX() is rvalue• rvalues can only by on the right side of
assignment• (opposite are lvalues)
But why an rvalue?
• Result of function call or expression evaluation is a temporary • Object exists temporarily until expression in
which it occurs is evaluated, then dies
• C++ does not let you modify temporaries• Does not let you use them as lvalues
Our Errors
• Read() tries to modify result of function call, a temporary - Error
• Write doesn't try to modify temporary returned by the function call P.reflectX()• Why is this a problem then?
Compiler Doesn’t Know
• Doesn’t know function won’t modify temporary
• So tell it…using const• Promise to compiler function won’t change
temporary
Quick Fix
• Const fixed everything
Why is write() a friend?
• Don’t need write() as friend• Can use public accessor functions
What is THIS error?
In function `void write(const Point &)':
passing `const Point' as `this' argument of `double Point::getX()' discards qualifiers
passing `const Point' as `this' argument of `double Point::getY()' discards qualifiers
• First off – “this” is a pointer to object whose member function was called• Called made to A.foo()
• Inside foo() this points to A
• Called made to B.foo()• Inside foo() this points to B
Errors
• In write() we have variable P • Type const Point &
• Compiler complains calling P’s (a const Point &) getX() discards qualifiers• const is a qualifier
• Compiler has no guarantee getx() won’t modify P
In function `void write(const Point &)': passing `const Point' as `this' argument of `double Point::getX()' discards qualifiers passing `const Point' as `this' argument of `double Point::getY()' discards qualifiers
Not Discarding Qualifiers
• We know getX() doesn’t modify P
• So let the compiler know…use const
• Syntax • Put const immediately after parenthesized
argument list to member function
double getX() const { return x; }
double getY() const { return y; }
Object Creation
How Many Objects Created?
• Quick answer -- 7Default constructor! Default constructor! (2,3) (-1,5) Copy constructor! Copy constructor! 2-arg constructor! Point dies! Point dies! Copy constructor! 2-arg constructor! Point dies! Point dies! (0,4) Point dies! Point dies! Point dies!
How Many Objects Created?
• Quick answer -- 7
Where It Happen?
• Points P & Q created with default constructors when defined
• Two calls to midpoint each create point they return with call to 2-argument constructor
• Where do 3 extra points come from? • All created with the copy constructor • From pass-by-value calls to midpoint & write
• All of this extra work can be avoided by using pass by reference (with const) instead!
Using Const (for optimization)
Output
Default constructor! Default constructor! (2,3) (-1,5) 2-arg constructor! 2-arg constructor! (0,4) Point dies! Point dies! Point dies! Point dies!
Things Get Messy
how many components? 3 Enter 3 values: 9.3 8.9 3.2 21.4 = 2.8771e-309 + 8.9 + 3.2
Why?
• Sum makes copy of V calls it A• When V.val is copied to A.val
A.val points to same array
• When sum() finished A’s
destructor is called• Deletes A.val• But that’s V.val too!
Two solutions
• Avoid pass-by-value, use pass-by-reference instead
• Define copy constructor that makes deep copy, including allocating new arrays
Make it Go Away!
• You can make it all go away by using pass-by-reference in conjunction with const• Java, for example, doesn’t even have pass-
by-value for user defined types