Sei sulla pagina 1di 12

C++ Function and Operator Overloading Assigned reading

pages 365-370 (function overloading) pages 502-515 (operator overloading) pages 518-524 (friends and operator<<)

Today well cover


Overloading vs. Overriding Overloading operators vs. functions Overloading class members vs. non-members Friends and overloading Type conversions, scopes and resolution
CSE 332: C++ function and operator overloading

Overriding vs. Overloading


Signature is what distinguishes overriding from overloading
Signature is operator/function name + ordered list of argument types Same name, same signature means overriding
E.g., D::add(int, long) and B::add(int, long) (same sig)

Same name, different signature means overloading


E.g., D::add(int, long) and B::add(long, int) (different sig)

Overriding (we covered this for virtual functions)


Same signature, but different scopes Derived class can give its own separate definition for function/operator If virtual, can be resolved polymorphically, using dynamic type If non-virtual, is resolved using static type (derived class hides base) Only member functions and member operators can be overridden

Overloading
Different signatures in a common scope, declarative scopes may differ Each overloaded operator or function must have its own definition Can overload non-member functions and operators too!

CSE 332: C++ function and operator overloading

Function/Operator Overloading
class A { public: A (int i) : a_(i) {} int a () {return a_;} bool operator==(const A &a); private: int a_; };
// member operator bool A::operator==(const A &a) { // note: object itself is // the first argument return a_ == a.a_; } // non-member operator bool operator< (const A &lhs, const A &rhs) { return lhs.a() < rhs.a(); }

Remember an implicit this pointer is passed to any non-static member function Member functions/operators
The object on which the call is made isnt in the argument list Member function is passed a this pointer instead

Non-member functions/operators
Both objects appear in the functions argument list No this pointer is involved

Both operators are binary

CSE 332: C++ function and operator overloading

Overloading Operators
class complex { double real_, imaginary_; public: complex(double r, double i) : re(r), im(i) {} complex operator+(complex); complex operator*(complex); };
int main (int, char *[]) { complex w(1,0), x(2,2); complex y = w.operator+(x); complex z = w + x; }

Cant add operators


Can only overload existing ones

Cannot change operators # of arguments


Operator has a fixed arity: unary, binary, etc.

Can invoke with either of two syntaxes: obj1.operator+(obj2) is same as obj1+obj2


CSE 332: C++ function and operator overloading

Restrictions on Overloading Operators


For overloaded operators, precedence rules apply
So, itd be a bad idea to overload ^ to mean exponentiation But, its fine to overload << for output or >> for input

Cant overload some of them for user-defined types


sizeof (instance/type memory size) :: (scope resolution) . (member selection via variable/reference) .* (member selection via pointer) ?: (conditional operator) typeid (Run Time Type Identification information) static_cast (all the cast operators) dynamic_cast const_cast reinterpret_cast
CSE 332: C++ function and operator overloading

Declaring Operators (General Rules)


Binary operators can be declared in either one of two ways (as before) a.operator+(b) operator+(a, b) (non-static member function) (non-member function)

if both are defined, overload resolution determines which to use (but dont do this)

Unary operators also have both prefix and postfix forms


Prefix

a.operator++() operator++(a)
Postfix

(non-static member function) (non-member function)

a.operator++(int) operator++(a, int)

(non-static member function) (non-member function)

Note: return types are not considered in overload resolution

CSE 332: C++ function and operator overloading

Predefined Meanings of Some Operators


Operators = , [], and ->
Must ensure their first operands are l-values Can do this by defining as non-static member function Foo& Foo::operator= (const Foo& f) {} Otherwise, can define as a non-member function, but then the first argument should be a non-const reference Foo& operator= (Foo& l, const Foo& r) {}

Many operators have predefined meanings


Follow the principle of least surprise E.g., + that pastes RHS onto end of LHS is reasonable E.g., + that pastes RHS onto front of LHS wouldnt be

Enumerations are user defined types so you can define operators that are overloaded for them too!
void operator++ (BinFlag& b){b=(b*2)%TOP;}
CSE 332: C++ function and operator overloading

Scopes and Operator/Function Resolution


X x; Y y; x += y; // which definition to use?
If X is a class and it or a base class defines += then use that definition; Otherwise, find a definition for operator+=(X, Y) in the context of the current program scope; if X is defined in namespace N then look there; if Y is defined in namespace M then look there;

CSE 332: C++ function and operator overloading

Type Conversion Operators Converts object to another type (explicitly)


class Number { public: Number() : val_(0) {} Number(int i) : val_(i) {}

// name is type, no return or arguments operator int () const {return val_;} private: int val_; }
Number n(4); int i = n;
CSE 332: C++ function and operator overloading

Friends and Overloading


class A { friend ostream & operator<< (ostream &o, const A &a); private: int a_; }; ostream & operator<< (ostream &o, const A &a){ // accesses private a_ o << "A::a_ = " << a.a_; return o; } int main (int, char * []) { A a; cout << a << endl; return 0; }

Overloading can add new behaviors to a class


For example, printing an A

We cant change the ostream class


So, use its public member functions and operators Modify our class instead

Our class is the right hand side argument


So, have to use nonmember function/operator Often make that function or operator a friend

CSE 332: C++ function and operator overloading

When to Override and When to Overload


Use virtual member function overriding to provide different variations of the same abstraction (is-a)
Base::add(int) vs. Derived::add(int)

Use overloading when you want to provide related interfaces to similar abstractions
add(int&, int) vs. add(string&, const string&)

Use different names when the abstractions differ


add(int&, int) vs. subtract(int&, int)

CSE 332: C++ function and operator overloading

For Next Time C++ Templates


Another form of polymorphism (interface based) Let you plug different types into reusable code

Assigned Readings
pages 370-388 (function templates, specialization) pages 744-777 (class templates) pages 801-805 (nested class templates)

CSE 332: C++ function and operator overloading

Potrebbero piacerti anche