ch. 12: operator overloading - tarleton state university · 2019-12-16 · operator overloading is...

77
Ch. 12: Operator Overloading

Upload: others

Post on 02-Jun-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Ch. 12: Operator Overloading

Page 2: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operator overloading is just “syntactic sugar,” i.e. another way to make a function call:

shift_left(42, 3); 42 << 3;

The difference is that the arguments for this function don’t appear inside parentheses, but instead they surround or are next to the operator’s character(s).

example

Page 3: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Let’s first understand what we’re trying to do!

Just a “wrapper” for the int type!

Page 4: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

We would like to operate with Integer objects the same way we operate with int!

Page 5: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Wait a second! Isn’t + a binary operator?

Page 6: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Yes, but, when defined as member function, the LEFT operand is always the object, so only the RIGHT operand needs to be passed.

Page 7: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Why is the return value const?

Page 8: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

In order to prevent “crazy” uses like (x + y) = z;

Page 9: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Write the member function to overload the division / operator.

QUIZ

Page 10: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

If we want to use this function, we must #include <cassert>

Note: The author of the text has his own, customized version of assert, called require:

…..

Page 11: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Now let’s overload the compound assignment operator +=

Page 12: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

. . .

Why non-const and why reference?

Page 13: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

. . .

Non-const to allow uses accepted in C: (x += y) += z;Reference to prevent the creation of a copy.

Page 14: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

. . .

If this is a pointer to the current object, *this is …

Page 15: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 16: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Unary operators

. . .

declarations

Since only one operator is needed, if we want it passed explicitly, we have to use global functions:

definitions

Page 17: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

. . .

definitions

Page 18: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

If we want to use member functions, then no argument is passed!

. . .

Page 19: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

When the compiler sees ++a (a pre-increment), it generates a call to operator++(a); but when it sees a++, it generates a call to operator++(a, int). That is, it differentiates between the two forms by making calls to different overloaded functions.

Pre- and post-

increment

Page 20: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Write the member function to overload the subtraction –operator.

Clearly explain the choices you make for:• Return value• Argument(s)

QUIZ

Page 21: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

The choices for:• Return value:

• Value, b/c we’re creating a new variable, and we don’t want a leaked reference

• const , b/c we want to forbid (a – b) = 42;• Argument(s):

• Only rv if we make it a member function• const for safety, since the function should not modify the

argument• Reference to avoid making a copy (in case of large object).

QUIZ

Page 22: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Based on their “signatures” (i.e. function headers), explain what the compiler does when it encounters each operator.

QUIZ

What is this type of argument called?

Page 23: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

When the compiler sees ++a (a pre-increment), it generates a call to operator++(a); but when it sees a++, it generates a call to operator++(a, int). That is, it differentiates between the two forms by making calls to different overloaded functions.

QUIZ

Page 24: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Why does Integer have to “befriend” all these functions?

QUIZ

. . . .

Page 25: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

B/c they’re global functions that need to access a private member.

Solution

. . . .

Page 26: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Read and take notes:Binary operators

Page 27: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

1.If you only need to read from the argument and not change it, default to passing it as a const reference. • Ordinary arithmetic operations (like + and –, etc.) and

Booleans will not change their arguments, so pass by const reference is predominantly what you’ll use.

• When the function is a class member, this translates to making it a const member function.

Arguments & return values - GUIDELINES -

Page 28: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

1.If you only need to read from the argument and not change it, default to passing it as a const reference. • Only with the operator-assignments (like +=) and the

operator=, which change the left-hand argument, is the left argument not a constant, but it’s still passed in as an address because it will be changed.

Arguments & return values - GUIDELINES -

Page 29: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

2. The type of return value you should select depends on the expected meaning of the operator. • If the effect of the operator is to produce a new value,

you will need to generate a new object as the return value. For example, Integer::operator+ must produce an Integer object that is the sum of the operands. This object is returned by value as a const, so the result cannot be modified as an lvalue.

Arguments & return values - GUIDELINES -

Page 30: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Arguments & return values

3. All the assignment operators modify the lvalue. To allow the result of the assignment to be used in chained expressions, like a=b=c, it’s expected that you will return a reference to that same lvalue that was just modified. • But should this reference be a const or nonconst?

Although you read a=b=c from left to right, the compiler parses it from right to left, so you’re not forced to return a nonconst to support assignment chaining.

- GUIDELINES -

Assignment is right-associative

Page 31: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

What is the output?

QUIZ

a = b = c = d ;

Page 32: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

It’s the same as if parenthesized

thus:

QUIZ

a = b = c = d ;

Page 33: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

3. All the assignment operators modify the lvalue. To allow the result of the assignment to be used in chained expressions, like a=b=c, it’s expected that you will return a reference to that same lvalue that was just modified. • However, people do sometimes expect to be able to perform

an operation on the object that was just assigned to, such as (a=b).func( ); to call func( ) on a after assigning b to it. Thus, the return value for all of the assignment operators should be a nonconst reference to the lvalue.

Arguments & return values - GUIDELINES -

Page 34: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

vs.

Returning a temporarya.k.a. the return value optimization

If we do the return this way, the compiler builds the object directly into the location of the outside return value.• Only the constructor is called.• No copy-constructor is called!• No destructor is called (no object in this function’s scope – leave it to the caller’s

scope!)

This is how what we explained in ch.11. Constructor, copy-constructor, and destructor are called.

Page 35: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Individual work for next time:End-of-chapter exercises 1, 2, 3

EOL 1

Page 36: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

SKIP:

operator[]newdeletecomma operator ,operator ->*

Page 37: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operator ->

Remember how we have used it so far: the LHS must be a pointer (to a struct, union or class).

When we overload it, it is because we want to make an object appear to be a pointer.

Since such an object has more “smarts” built into it than a typical pointer, it is called a smart pointer.

Page 38: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operator ->

Especially useful if you want to:

• “wrap” a class around a pointer to make it safe

• create an iterator (object that moves through a collection/container of other objects and selects them one at a time, without providing direct access to the implementation of the container)

Page 39: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operator ->

A pointer dereference operator must:

• be a member function

• return an object (or reference to an object) that also has a pointer dereference operator, or

• return a pointer that can be used to select what the pointer dereference operator arrow is pointing at.

example

Page 40: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

These objects are used in the text program C12: SmartPointer.cpp

Page 41: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 42: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 43: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

. . . . .Member function of

the vector class

nullptr

Page 44: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 45: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Abort at the end of container

Let’s understand this!sp is an object of class SmartPointer …

(next slide)

Page 46: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 47: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Shouldn’t it besp -> -> f()instead?

Page 48: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Shouldn’t it besp -> -> f()instead?

A: No, because oc is a reference, which automatically dereferences itself!!

Page 49: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

It’s more common to see a “smart pointer” or “iterator” class nested within the class that it services – see the following example C12:NestedSmartPointer.cpp

We shall examine the nested smart pointer example in the lab.

Page 50: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operators you can’t overload• The member selection operator .

• The pointer to member dereference operator .*

• There’s no exponentiation operator.– The most popular choice for this was operator** from

Fortran, but it raised difficult parsing questions for compilers.

– Also, C has no exponentiation operator, so C++ didn’t seem to need one either because you can always perform a function call.

Page 51: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Operators you can’t overload

• There are no user-defined operators.

• For existing operators, we can’t change:– precedence rules– nr. of arguments.

Page 52: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

To do for next time:

Solve end-of-chapter exercises 4, 5

EOL 2

Page 53: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Non-member operators

If it doesn’t make any difference whether we overload the operators with member or global functions, it is recommended to choose member functions; this emphasizes the association between the operator and its class.

Page 54: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Non-member operatorsHowever, sometimes you want the left-hand operand to be an object of some other class. Application: when the operators << and >> are overloaded for iostreams; we want to be able to write:

MyClass myObject;cout <<myObject;cin >>myObject;

Since iostreams is a fundamental C++ library, you’ll probably want to overload these operators for most of your classes, so the process is worth memorizing

Page 55: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

C12:IostreamOperatorOverloading.cpp

Making friends with two global functions that overload the operators << and >>

The operator [] is overloaded through a member function

Page 56: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Global function definitions

These are the original versions of the operators, from <iostream>

Page 57: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Global function definitions

Why by reference? B/c we want the external objects to change after applying the overloaded operators.

Page 58: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Global function definitions

Why return anything? It would be simpler to make the functions void!A: We want to be able to use the returned ostream and istream in a more complex expression (see next slides for example).

Page 59: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

This is how the operators are employed in user code

stringstream is a stream class that allows easy operation on strings.Objects of this class use a string buffer that contains a sequence of characters.Characters can be inserted and/or extracted from the stream using any operation allowed on both input and output streams.

Page 60: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Is it legal to do this?

IntArray I1, I2;

. . . .

input >> I1 >>I2;

A: Yes, but only because the overloading function returns the stream!

Page 61: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Overloading assignment =

Remember the rule: the copy-constructor is called(only) when a new object is created from an existing object!

Default constructor

Copy constructor

Overloaded operator =

Doesn’t the copy constructor take care of assignment?

Page 62: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

The right-hand side does not even need to be a user-defined object:

Assignment syntax, equivalent to

Fee fee(1);

This constructor is called

Page 63: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Conclusion: Any time we’re initializing an object using an =instead of the ordinary function-call form of the constructor, the compiler will look for a constructor that accepts whatever is on the right-hand side.

Page 64: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 65: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

One simple rule: copy all of the necessary information from the right-hand object into the current object (that is, the object that operator= is being called for)

Page 66: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

… and one common mistake:

not checking first for self-assignment!

In some cases, such as this one, it’s harmless if you perform the assignment operations anyway, but if changes are made to the implementation of the class, it can make a difference, and if you don’t do it as a matter of habit, you may forget and cause hard-to-find bugs.

example

Page 67: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Pointers in classes

Problem: Simply copying a pointer means that you’ll end up with two objects pointing to the same storage location.

Solution: You need to do bookkeeping of your own.

example

Important case in which self-assignment is dangerous:

Page 68: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 69: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,
Page 70: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Simply copy whatever the pointer refers to.(Also works for copy-

construction.)

Page 71: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Draw a memory map!

Page 72: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Problem with the copy technique

If the object requires a lot of memory or time for initialization, copying is not efficient.

Solution: next slide

Page 73: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Reference counting

You give intelligence to the object that’s being pointed to so it knows how many objects are pointing to it.

Both copy-construction and assignment mean: attaching another pointer to an existing object and incrementing the reference count.

Destruction means: decrementing the reference count. If the reference count goes to zero, destroy the object!

Page 74: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Read and understand C12:ReferenceCounting.cpp

Page 75: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Automatic operator= creation

Because assigning an object to another object of the same type is an activity most people expect to be possible, the compiler will automatically create a type::operator=(type)if you don’t make one.

The behavior of this operator mimics that of the automatically created copy-constructor; if the class contains objects (or is inherited from another class), the operator=for those objects is called recursively, a.k.a. memberwise assignment.

Page 76: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

Remember from ch.11:“Deleted” functions were

introduced in C++11

We can disable the use of assignment for a class

Page 77: Ch. 12: Operator Overloading - Tarleton State University · 2019-12-16 · Operator overloading is just “syntactic sugar,” i.e. another way to make a function call: shift_left(42,

We stop before the section Automatic type conversion

SKIP the remainder of ch.12

EOL 3