0% found this document useful (0 votes)
15 views

C++ Overloading

Overloading allows the same function or operator name to be used with different signatures. Signatures are distinguished by argument types and return types are not considered. The most specific match is used to resolve which overloaded function or operator to call. Overloading is resolved at compile-time based on signatures, while overriding uses run-time polymorphism based on an object's type. Overloaded functions and operators should have symmetric and consistent behavior and obey precedence rules. Member and non-member overloading both have appropriate uses depending on whether the class is involved in one or both parameter types.

Uploaded by

ashutosh91
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

C++ Overloading

Overloading allows the same function or operator name to be used with different signatures. Signatures are distinguished by argument types and return types are not considered. The most specific match is used to resolve which overloaded function or operator to call. Overloading is resolved at compile-time based on signatures, while overriding uses run-time polymorphism based on an object's type. Overloaded functions and operators should have symmetric and consistent behavior and obey precedence rules. Member and non-member overloading both have appropriate uses depending on whether the class is involved in one or both parameter types.

Uploaded by

ashutosh91
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 7

Overview of C++ Overloading

Overloading occurs when the same operator or


function name is used with different signatures
Both operators and functions can be overloaded
Different definitions must be distinguished by their
signatures (otherwise which to call is ambiguous)
Reminder: signature is the operator/function name and the
ordered list of its argument types
E.g., add(int,long) and add(long,int) have different
signatures
E.g., add(const Base &) and add(const Derived &)
have different signatures, even if Derived is-a Base
Most specific match is used to select which one to call

CSE 332: C++ Overloading

Overloading vs. Overriding


Overriding a base class member function is
similar to overloading a function or operator
But for overriding, definitions are distinguished by
their scopes rather than by their signatures

C++ can distinguish method definitions


according to either static or dynamic type
Depends on whether a method is virtual or not
Depends on whether called via a reference or
pointer vs. directly on an object
Depends on whether the call states the scope
explicitly (e.g., Foo::baz();)
CSE 332: C++ Overloading

Function Overloading
class A {
public:
int add(int i, int j);

Calls to overloaded functions and


operators are resolved by
Finding all possible matches based
on passed arguments

// not allowed, would be


// ambiguous with above:
// long add(int m, int n);

May involve type promotion


May involve instantiating templates

Finding the best match among


those possible matches

// Ok, different signature


long add(long m, long n);
};

Signature does not include the


return type

int
main (int argc, char **argv) {
int a = 7;
int b = 8;
int c = add(a, b);
return 0;
}

CSE 332: C++ Overloading

Which might not help even if it did,


i.e., calls may ignore result
So, overloading cant be resolved by
return type alone
Compiler generates an error if the
call cant be resolved

Operator Overloading
class A {
friend ostream &operator<<
(ostream &, const A &);
private:
int m_;
};

Similar to function
overloading

ostream &operator<<

(ostream &out, const A &a) {


out << "A::m_ = " << a.m_;
return out;
}
int main () {
A a;
cout << a << endl;
return 0;
}

CSE 332: C++ Overloading

Resolved by signature
Best match is used

But the list of operators and


the arity of each is fixed
Cant invent operators (e.g.,
like ** for exponentiation )
Must use same number of
arguments as for built-in types
(except for operator())
Some operators are off limits
:: (scope) ?: (conditional)
.* (member dereference)
. (member) sizeof
typeid (RTTI)

Operator Symmetry, Precedence


class Complex {
public:
// Constructor
Complex (double r, double i);
friend Complex operator*
(const Complex &, const Complex &);
// but not friend Complex operator^
// (const Complex &, const Complex &);
private:
int real_;
int imaginary_;
};
// multiplication works just fine
Complex operator* (const Complex &,
const Complex &);
// exponentiation operator unworkable
// Complex operator^ (const Complex &,
//
const Complex &);

CSE 332: C++ Overloading

Make arithmetic
operators symmetric
As non-member friends
Return result by value
Dont mix base and
derived types in their
parameter lists

Operators for userdefined types obey the


same precedence rules
as for built-in types
Can lead to some
unexpected mistakes
E.g., if uncommented
exponentiation for

a + b * c ^ 2

Member vs. Non-Member Overloading


// declarations in .h file
class A {
public:
friend bool operator<
(const A &, const A &);
A operator++(); // prefix
A operator++(int); // postfix
private:
int m_;
};
bool operator==(const A &lhs,
const A &rhs);
// definitions in .cpp file
bool operator==(const A &lhs,
const A &rhs)
{return lhs.m_ == rhs.m_;}

A A::operator++() // prefix
{++m_; return *this;}

Remember a this pointer is passed


to any non-static member function
Object doesnt appear in parameters
For non-member functions and
operators all parameters are listed

The rules about operator arity are


obeyed in code on left
Operator == is binary
Prefix/postfix ++ are unary, parameter
for postfix distinguishes its signature

Must declare and define [] and ==


and -> and () as member operators
Non-member operators are needed
when working with classes you wrote
and classes you didnt write
E.g., ostream << and istream >>

Non-member operators are also


useful to preserve symmetry

A A::operator++(int) // postfix
{A ret(*this); ++*this; return ret;}

CSE 332: C++ Overloading

E.g., for arithmetic/relational operators


May help to avoid unexpected type
conversions, especially with an
inheritance hierarchy

Summary: Tips on Overloading


Use virtual overriding when you want to substitute
different subtypes polymorphically
E.g., move() in derived and base classes

Use overloading when you want to provide related


interfaces to similar abstractions
E.g., migrate(Bird &) vs. migrate(Elephant &)
Make[] -> () = *= ++ -- etc. members
Make << >> + * - / == < etc. non-members

Use different names when the abstractions differ


E.g., fly() versus walk()
CSE 332: C++ Overloading

You might also like