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 -- 7 Default 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

Class7

  • 1.
    Const and theCopy Constructors
  • 2.
    Object Oriented ParadigmSeparating interface from implementation Constructors & destructors Public vs private Not C++ specific
  • 3.
    Const – specificto C++ const keyword Ensures initialized value is its only value ever Sometimes it’s a promise
  • 4.
  • 5.
    No call toRead/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
  • 6.
    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)
  • 7.
    But why anrvalue? 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
  • 8.
    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?
  • 9.
    Compiler Doesn’t KnowDoesn’t know function won’t modify temporary So tell it…using const Promise to compiler function won’t change temporary
  • 10.
    Quick Fix Constfixed everything
  • 11.
    Why is write()a friend? Don’t need write() as friend Can use public accessor functions
  • 12.
    What is THISerror? 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
  • 13.
    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
  • 14.
    Not Discarding QualifiersWe 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; }
  • 15.
  • 16.
    How Many ObjectsCreated? Quick answer -- 7 Default 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!
  • 17.
    How Many ObjectsCreated? Quick answer -- 7
  • 18.
    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!
  • 19.
    Using Const (for optimization)
  • 20.
    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!
  • 21.
    Things Get Messyhow many components? 3 Enter 3 values: 9.3 8.9 3.2 21.4 = 2.8771e-309 + 8.9 + 3.2
  • 22.
    Why? Sum makescopy 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!
  • 23.
    Two solutions Avoidpass-by-value, use pass-by-reference instead Define copy constructor that makes deep copy , including allocating new arrays
  • 24.
    Make it GoAway! 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