function overloading c++ supports writing more than one ... · overloading operators in c++ • c++...

21
1 Function Overloading C++ supports writing more than one function with the same name but different argument lists How does the compiler know which one the programmer is calling? They have different signatures A function’s signature is a combination of its name and its argument list the return type is not part of the signature so you can’t overload just by changing return type

Upload: others

Post on 02-Jun-2020

12 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

1

Function Overloading

• C++ supports writing more than one function with the same name but different argument lists

• How does the compiler know which one the programmer is calling? – They have different signatures

– A function’s signature is a combination of its name and its argument list

– the return type is not part of the signature – so you can’t overload just by changing return type

Page 2: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

2

When you use function overloading, ambiguity can

happen in 3 cases:

1. if you have call by reference and call by value with the same parameters’ types:

void square (double& x)

{ x = x * x; }

void square (double x)

{ cout << x * x; }

2. if there is no matching parameter type for a called function but variables can be automatically converted to appropriate types:

int area (int height, int width)

{ return height * width; }

double area (double height, double width)

{ return height * width; }

3. if you use default arguments: prototypes:

void fcn(int a, int b = 9, double c = 1.33);

void fcn(int a, int b);

Page 3: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

3

Function Overloading (cont.)

Suppose that we have a scenario such as: void swap (int *a, int *b);

void swap (double *x, double *y);

void swap (bool *p, bool *q);

int main()

{

int i = 4, j = 6;

double c = 13.2, d = 43.1;

bool flag1 = TRUE, flag2 = FALSE;

swap (&i, &j);

swap (&c, &d);

swap (&flag1, &flag2);

}

with function definitions as shown on the next slide:

Page 4: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

4

void swap (int *a, int *b)

{

int temp;

temp = *a;

*a = *b;

*b = temp;

}

void swap (double *x, double *y)

{

double temp;

temp = *x;

*x = *y;

*y = temp;

}

void swap (bool *p, bool *q)

{

bool temp;

temp = *p;

*p = *q;

*q = temp;

}

Each of these functions

expects to see pointers as

arguments –

the only difference is what

kind of thing the pointer

argument is pointing to

• The compiler matches up the

signature in the function

definition with the call so that the

correct version gets invoked

Page 5: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

5

Remember Function Templates

• No need for 3 different functions

• We could create a function template definition for swap

– the function template sets up the framework for the functions we

need, then based on how the template is called, the compiler

generates the necessary code

Example:

template <typename T> void swap(T *a, T *b)

{

T temp;

temp = *a;

*a = *b;

*b = temp;

}

the keyword template tells the compiler it’s a function template

everywhere a T occurs in the template,

the compiler will substitute the correct

type depending on the call to the function

this is the function’s return type – here

it is void because the original swap

functions had void return type

Page 6: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

6

One More (trivial) Template Example -

template <class T> T square (T x)

{

return x * x;

}

if called with an int argument, this will return an int

result; if called with a double argument, it will return a

double.

Page 7: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

7

Object Oriented Design

Where do we stand now?

• We’ve talked about classes and their definition – class definition in <classname>.h file

• this defines the interfaces for the class

– implementation of the methods in <classname>.cpp file

• We’ve talked about constructors and destructors – default constructor and overloaded constructors

– issues to consider when a class has a member that is dynamic

– order of method invocation as a program runs (explored through a trace of what happens in an example using the point class)

• We discussed copy constructors and saw an example

Page 8: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

8

Just to remind you:

Constructors: What Happens by Default

• If you do not define a constructor, the system will define a default constructor

• the default constructor is supposed to initialize all numeric types to 0, all pointers to null, and all Boolean types to false (but be careful – check that it really does this!)

• If you do define a constructor, yours will be used whenever an object of this type is instantiated – that is, whenever an object is declared or new or gcnew is called

to create an object of this type

• If you provide a constructor that takes a nonvoid parameter, you must also provide a default constructor.

• objects of managed classes must always be declared as tracking handles (otherwise you’ll get a compile error)

Page 9: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

9

Destructors: What Happens by Default

• A destructor is a function that: – Is automatically invoked when an object is destroyed

• i.e. at the end of the block in which an object was declared

– Performs termination housekeeping • In particular, it recovers memory to be reused

• On block exit, destructors for objects declared in the block are called in reverse order of object instantiation (see class example)

– Takes no arguments and returns no value

– Has the same name as the class preceded by a ~

• There is only one destructor for a class – no overloading is possible

• The system automatically generates a destructor for a class, but … – Programmers do have to write a destructor when their class

dynamically allocates memory (which can happen when data members are pointers or array names or CLI objects)

Page 10: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

10

= Operators: What Happens by Default

• Ordinarily, the compiler will generate a default

assignment operator

– a point class (that has two double data members) is

an example of a case in which the = operator is

automatically overloaded by the compiler

• If you define any assignment operator that takes

the class as a parameter, the compiler cannot

generate a default assignment operator for that

class.

• In these cases, you have to provide an

overloaded assignment operator

Page 11: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

11

Why do we need a copy constructor?

• If a copy constructor is missing (for any class),

the compiler creates a default one that performs

member-by-member copying.

• For classes that have dynamic members, we

need to have appropriate memberwise copy

functions (we’ve seen an example of why)

• Let’s revisit the class MemberInfo that we looked

at before

– We’re going to look at 4 different ways to represent

the same information – then consider how statements

execute differently (and why)

Page 12: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

12

Class MemberInfo header: #pragma once

#ifndef MEMB1

#define MEMB1

using namespace System;

ref class MemberInfo{

public:

MemberInfo(); // default constructor

MemberInfo(MemberInfo %); // copy constructor

void enterName(); // method for entering name

void enterAge(); // method for entering age

String^ getName(); // method for extracting name

int getAge(); // method for extracting age

void setName(String^); // method for setting name to a value

void setAge(int); // method for setting age to a value

void display(); // method for display of the object’s data

~MemberInfo(); // destructor

private:

String ^name;

int age;

static int count;

};

#endif

Page 13: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

// MANAGED CLASS

ref class MemberInfo{

public:

static int count;

MemberInfo();

MemberInfo(MemberInfo %);

void enterName();

void enterAge();

String^ getName();

int getAge();

void setName(String^);

void setAge(int);

void display();

~MemberInfo();

private:

String ^name;

int age;

};

// STANDARD C++ CLASS

// copy constructor w/ ref parameter

class MemberInfo{

public:

static int count;

MemberInfo();

MemberInfo(MemberInfo &);

void enterName();

void enterAge();

string* getName();

int getAge();

void setName(string*);

void setAge(int);

void display();

~MemberInfo();

private:

string * name;

int age;

};

M_Info Native M_Info2

Page 14: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

// STANDARD C++ CLASS

// pointer to string type data member

class MemberInfo{

public:

static int count;

MemberInfo();

MemberInfo(MemberInfo *);

void enterName();

void enterAge();

string* getName();

int getAge();

void setName(string*);

void setAge(int);

void display();

~MemberInfo();

private:

string * name;

int age;

};

// STANDARD C++ CLASS

// string type data member

class MemberInfo{

public:

static int count;

MemberInfo();

MemberInfo(MemberInfo &);

void enterName();

void enterAge();

string getName();

int getAge();

void setName(string);

void setAge(int);

void display();

~MemberInfo();

private:

string name;

int age;

};

Native M_Info1 Native M_Info

Page 15: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

What happens with = and ==? • M_Info

– Has members • MemberInfo(MemberInfo %);

• String ^name;

– Does not allow this sequence of statements • MemberInfo ^n1, ^n2;

• *n1 = *n2; // error C2582: 'operator =' function is unavailable

– Allows this sequence of statements: • if (n1 == n2) cout << "equal \n";

• Native M_Info

– Has members • MemberInfo(MemberInfo &);

• string name;

– Allows this sequence of statements: • MemberInfo *n1, *n2;

• *n1 = *n2;

– Does not allow • if (n1 == n2) cout << "equal \n";

– // error C2678: binary '==' : no operator found which takes a left-hand operand of type 'MemberInfo' (or there is no acceptable conversion)

Executes the default assignment operator

Why should this allow ==?

Page 16: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

What happens with = and ==?

• Native M_Info 1 – Has members

• MemberInfo(MemberInfo *);

• string * name;

• int age;

– Allows • MemberInfo *n1, *n2;

• *n1 = *n2;

• if (n1 == n2) cout << "equal \n";

• Native M_Info 2 – Has members

• MemberInfo(MemberInfo &);

• string* name;

• int age;

– Allows • MemberInfo *n1, *n3;

• *n1 = *n3;

• if (n1 == n3) cout << "equal \n";

Why should this allow assignment and ==?

Why should this allow assignment and ==?

Moral of the story: Be sure you know what = (assignment) and == (equality test)

really mean for your class!

Page 17: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

Overloading Operators in C++

• C++ allows the programmer to redefine the function of

most built-in operators on a class-by-class basis

• the operator keyword is used to declare a function that

specifies what an operator symbol (such as = or +)

means when it is applied to instances of a class

– this gives the operator more than one meaning, and the compiler

determines what meaning is intended by looking at the types of

its operands

• syntax:

type operator <operator-symbol> (parameter-list)

• Example: overloading the addition operator and the

assignment operator for a class Complex that is intended

to represent complex numbers

Page 18: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

Example

Class to represent complex numbers: header (class definition file)

#pragma once

#include <iostream>

using namespace System;

using namespace std;

class Complex

{

public:

Complex ();

Complex (double r, double i);

Complex operator+ (Complex &other);

Complex & Complex::operator = (Complex &n);

void display();

private:

double re,im;

};

Page 19: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

.cpp source (implementation) file for for class Complex

#include "stdafx.h"

#include " Complex.h"

Complex::Complex (){

re = 0.0;

im = 0.0;

}

Complex::Complex(double r, double i){

re = r;

im = i;

}

Complex Complex::operator + (Complex &other){

return Complex (re + other.re, im + other.im);

}

Complex & Complex::operator = (Complex &n){

re = n.re;

im = n.im;

return *this;

}

void Complex::display(){

cout << re << "," << im << endl;

}

Overloaded addition

operator

Overloaded assignment

operator

Page 20: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

Example of a small program using class Complex:

#include "stdafx.h"

#include <iostream>

#include "Complex.h"

using namespace System;

using namespace std;

int main(array<System::String ^> ^args)

{

Complex a = Complex(1.2, 3.4);

Complex b(3.4, 5.6);

Complex c;

c = a + b;

c.display();

return 0;

}

Page 21: Function Overloading C++ supports writing more than one ... · Overloading Operators in C++ • C++ allows the programmer to redefine the function of most built-in operators on a

Not every operator can be overloaded!

Operators that can be overloaded

+ - * / % ^ & |

~ ! = < > += -= *=

/= %= ^= &= |= << >> >>=

<<= == != <= >= && || ++

-- ->* , -> [] () new delete

new[] delete[]

Operators that cannot be overloaded

. .* :: ?: sizeof