Professional Documents
Culture Documents
Unit Ii
Unit Ii
What is a constructor?
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function }; rectangle::rectangle(float h, float w) { height = h; width = w; xpos = 0; ypos = 0; }
Comments on constructors
A constructor is called automatically whenever a
new instance of a class is created. You must supply the arguments to the constructor when a new instance is created. If you do not specify a constructor, the compiler generates a default constructor for you (expects no parameters and has an empty body).
Overloading constructors
You can have more than one constructor in a class,
as long as each has a different list of arguments.
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor rectangle(); // another constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function };
Operator Overloading
They need to avoid self assigment Self Assigment is stuff like Object A; A=A;
Now, normally this would never happen.. but, depending on how pointers are cast, or whatever, it can. So you have to be careful.
Operator Overloading =
const Employee &Employee::operator=(const Employee &rhs) { if ( this == &rhs ) return *this; id = rhs.getId(); name = new char[strlen(rhs.getName()) + 1]; strcpy(name,rhs.name); return *this; }
Rule of 3
either a destructor, overloaded assignment operator or copy constructor, it generally needs ALL 3.
What is a destructor?
It is a member function which deletes an object. A destructor function is called automatically when
the object goes out of scope:
(1) the function ends (2) the program ends (3) a block containing temporary variables ends (4) a delete operator is called (i) the same name as the class but is preceded by a tilde (~) (ii) no arguments and return no values
A destructor has:
class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor }; string::string(char *c) { size = strlen(c); s = new char[size+1]; strcpy(s,c); } string::~string() { delete []s; }
Comments on destructors
compiler generates a default destructor for you. When a class contains a pointer to memory you allocate, it is your responsibility to release the memory before the class instance is destroyed.
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor rectangle(const rectangle&); // copy constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function };
rectangle::rectangle(const rectangle& old_rc) { height = old_rc.height; width = old_rc.width; xpos = old_rc.xpos; ypos = old_rc.ypos; } void main() { rectangle rc1(3.0, 2.0); rectangle rc2(rc1); rectangle rc3 = rc1; C++ statements; }
// use constructor // use copy constructor // alternative syntax for // copy constructor
#include <iostream.h> #include <string.h> class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor void print(); void copy(char *); }; void string::print() { cout << s << endl; }
void string::copy(char *c) { strcpy(s, c); } void main() { string str1("George"); string str2 = str1; // default copy constructor str1.print(); str2.print(); // what is printed ?
Types
Built in (int, char) or user-defined Can use existing operators with user-defined types
Cannot create new operators
Overloading operators
Create a function for the class Name function operator followed by symbol
Operator+ for the addition operator +
Cannot change
How operators act on built-in data types
I.e., cannot change integer addition
Operators that can be overloaded + ~ /= <<= -new[] ! %= == ->* delete[] * = ^= != , / < &= <= ->
Operator Overloading
They need to avoid self assigment Self Assigment is stuff like Object A; A=A;
Now, normally this would never happen.. but, depending on how pointers are cast, or whatever, it can. So you have to be careful.
Operator Overloading =
const Employee &Employee::operator=(const Employee &rhs) { if ( this == &rhs ) return *this; id = rhs.getId(); name = new char[strlen(rhs.getName()) + 1]; strcpy(name,rhs.name); return *this; }
Rule of 3
either a destructor, overloaded assignment operator or copy constructor, it generally needs ALL 3.
Operator functions
Member functions
Similarly, overloaded >> needs istream & Thus, both must be non-member functions
Commutative operators
Suppose we have two different classes Overloaded operator can only be member function when its class is on left
HugeIntClass + Long int Can be member function
Example program
Class PhoneNumber
Holds a telephone number
1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 8.3: fig08_03.cpp // Overloading the stream-insertion and // stream-extraction operators. #include <iostream> using std::cout; using std::cin; using std::endl; using std::ostream; using std::istream; #include <iomanip> using std::setw;
fig08_03.cpp (1 of 3)
Notice function prototypes for overloaded operators >> and <<
They must be non-member friend functions, since the object of class Phonenumber appears on the right of // PhoneNumber class definition the operator. class PhoneNumber { cin << object friend ostream &operator<<( ostream&, const PhoneNumber & ); cout >> object friend istream &operator>>( istream&, PhoneNumber & ); private: char areaCode[ 4 ]; // 3-digit area code and null char exchange[ 4 ]; // 3-digit exchange and null char line[ 5 ]; // 4-digit line and null
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// overloaded stream-insertion operator; cannot be // a member function if we would like to invoke it with // cout << somePhoneNumber; ostream &operator<<( ostream &output, const PhoneNumber &num ) { The expression: output << "(" << num.areaCode << ") " cout << phone; << num.exchange << "-" << num.line; is interpreted as the function call: return output; // enables cout << a << b << c;
fig08_03.cpp (2 of 3)
This allows objects to be cascaded. cout << phone1 << phone2; ignore() skips specified // overloaded stream-extraction operator; cannot be first calls number of it with // a member function if we would like to invokecharacters from operator<<(cout, phone1), and input (1 by default). // cin >> somePhoneNumber; returns cout.
istream &operator>>( istream &input, PhoneNumber &num ) { Next, cout << phone2 executes. input.ignore(); // skip ( Stream manipulator setw input >> setw( 4 ) >> num.areaCode; // input area code number of characters restricts input.ignore( 2 ); // skip ) and space read. setw(4) allows 3 input >> setw( 4 ) >> num.exchange; // input exchange to be read, leaving characters input.ignore(); // skip dash (-) room for the null character. input >> setw( 5 ) >> num.line; // input line return input; // enables cin >> a >> b >> c;
Upcoming example
If non-static member function, needs one argument
class String { public: const String &operator+=( const String & ); ... };
y += z equivalent to y.operator+=( z )
Upcoming example
If non-member function, needs two arguments Example:
class String { friend const String &operator+=( String &, const String & ); ... };
y += z equivalent to operator+=( y, z )
Casting
Traditionally, cast integers to floats, etc. May need to convert between user-defined types
Example
Prototype
Also
A::operator int() const; A::operator OtherClass() const;
Prototype (non-member)
Friend Date &operator++( Date &); ++d1 same as operator++( d1 )
Prototype (non-member)
Return values
Preincrement
Returns by reference (Date &) lvalue (can be assigned)
Postincrement
Returns by value Returns temporary object with old value rvalue (cannot be on left side of assignment)
#include <iostream.h> class myclass { int a,b; public: myclass(){} myclass(int x,int y){a=x;b=y;} void show() { cout<<a<<endl<<b<<endl; } // these are friend operator functions // NOTE: Both the operans will be passed explicitely // operand to the left of the operator will be passed as the first argument and operand to the right as the second argument friend myclass operator+(myclass,myclass); friend myclass operator-(myclass,myclass); }; myclass operator+(myclass ob1,myclass ob2) { myclass temp; temp.a = ob1.a + ob2.a; temp.b = ob1.b + ob2.b; return temp; }
myclass operator-(myclass ob1,myclass ob2) { myclass temp; temp.a = ob1.a - ob2.a; temp.b = ob1.b - ob2.b; return temp; } void main() { myclass a(10,20); myclass b(100,200); a=a+b; a.show(); }