lecture 4 oop course. 4. operators using constructors: string int main(){ string s1(“my...
Post on 20-Dec-2015
235 views
TRANSCRIPT
Lecture 4Lecture 4
OOP Course
4. Operators4. Operators
Using constructors: StringUsing constructors: String
int main(){String s1(“My String”); String s2(s1);String s3;s3=s1;
}
int main(){String s1(“My String”); String s2(s1);String s3=s1;
}
What’s the difference?
Operators DefinitionOperators Definition• We want User-defined types to behave the same way as built-in types
• We want operators to be supported, for the uniform convention
• The language allows this
And the usage:
class String {char* chars;int length;
public:String();String(char* value);~String();String& operator=(String& operator=(constconst String& s); String& s);boolbool operator>( operator>(constconst String& s); String& s);String& operator+=(String& operator+=(constconst String& s); String& s);char* getString();void setString(char* value);
};
Operators - UsageOperators - Usage
• Who is the caller?
• Who is the parameter?
void main() {
String s1 =“OOP ”;
String s2 =“Course”;
s1 += s2;
}
Invokes “function”s1.operator+=(s2)
Operators - ImplementationOperators - Implementation
bool String::operator>(const string& s)
{
return strcmp(m_str, s.m_str) > 0;
}
Operators - ImplementationOperators - ImplementationString &String::operator+=(const String &s){
int new_len = length + s.length + 1;
char *v = new char [new_len];
strcpy(v, chars);
strcat(v, s.chars);
delete[] chars;
chars = v;
length = new_len;
return *this;
}
Within a member function: explicit name for the object on which the function is called
Operators – ImplementationOperators – Implementation(first version)(first version)
String String::operator+(const String &s){
String tmp = *this;
tmp += s;
return tmp;
}
Operators: Good newsOperators: Good news
• Can be defined and re-defined
• Defined by default: ==
• Rules:– At least one operand must be class– Cannot define new operators– Cannot change precedence/associativity
operators overloading - what can operators overloading - what can we overload?we overload?
+ - * / % ^ & | !
= < > += -= *= /= %=
^= &=|= << >> <<= >>= ==
!= <= >= && || ++ -- ,
->* -> () []
what not ? . .* :: ? : sizeof
Example: Class VectorExample: Class Vector
class Vector2D{private:
double x, y;public:
Vector2D(double x_init=0, double y_init=0):x(x_init), y(y_init){}
double getX() const {return x;}double getY() const {return y;}Vector2D add(const Vector2D& other) const {return Vector2D(x+other.x, y+other.y);}
}//usage:Vector2D a(3,2), b(1);Vector2D c = a.add(b);cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
Example: Class VectorExample: Class Vector
class Vector2D{private:
double x, y;public:
Vector2D(double x_init=0, double y_init=0):x(x_init), y(y_init){}
double getX() const {return x;}double getY() const {return y;}Vector2D operator+(Vector2D operator+(constconst Vector2D& other) Vector2D& other) constconst {{returnreturn Vector2D(x+other.x, y+other.y);} Vector2D(x+other.x, y+other.y);}
}//usage:Vector2D a(3,2), b(1);Vector2D c = a+b;Vector2D c = a+b;cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
Overloading ++ and --Overloading ++ and --
• Pre- and post-increment– x = 0; cout << x++; cout <<++x;
• Pre-increment and pre-decrement –– Vector2D operator++();
• Post-increment and post-decrement – use dummy parameter – Vector2D operator++(int);
Friend access modifierFriend access modifier
• The following will work:– c=a+b– c=a+1;
• The following will not work:– c=1+b
• The first argument cannot be built-in!• Solution: define the operator not as a member
function– But what about encapsulation?
• Access modifier friendfriend:: allows to access private fields and methods of the class
Example: Class VectorExample: Class Vectorclass Vector2D{
private:double x, y;
public:Vector2D(double x_init=0, double y_init=0):
x(x_init), y(y_init){}double getX() const {return x;}double getY() const {return y;}friend Vector2D operator+(
const Vector2D& left, const Vector2D& right);}Vector2D operator+(const Vector2D& left, const Vector2D& right){ return Vector2D(left.x+right.x, left.y+right.y);}//usage:Vector2D a(3,2), b(1);Vector2D c = a+b;cout << “(“ << c.getX() << “,” << c.getY() << ‘)’;
Class Vector: more operatorsClass Vector: more operatorsclass Vector2D{
. . . Vector2D operator-() const {return Vector2D(-x, -y);}double operator[](int index) const
{return (index == 0)?x:y;}friend ostream& operator<<(
ostream& ostr, const Vector2D& v);}ostream& operator<<(ostream& ostr, const Vector2D& v){
return ostr << “(“ << v.x << “,” << v.y << ‘)’;}
//usage:Vector2D a(3,2), b(1);Vector2D c = -a;cout << “(“ << c[0] << “,” << c[1] << ‘)’;cout << c << b << a;
Member vs. non-member operatorsMember vs. non-member operators
• Use membersUse members– When returning a reference
• operators =, []
– Unary operators, usually– Asymmetric operators, whenever possible
• Use friends forUse friends for– Symmetric operators– Operators on classes which cannot be altered
• istream, ostreamh
5 Operator=5 Operator=
operator=operator=
• By default: bitwise copy– Will this work for Vector2DVector2D?– Will this work for StringString?
• Rule of thumb: either you need all of {destructor, copy-constructor, operator=} or you need none
• Rules:MyClass& MyClass::operator=(const MyClass& other)
– Return *this*this– Define as member to ensure target object is
assignable
operator= : exampleoperator= : example
class String{. . .
public:String& operator=(const String& other){
if (this == &other) return *this;if (chars != NULL) delete[] chars;length = other.length;chars = new char[length+1];strcpy(chars, other.chars);return *this;
}
Operator examplesOperator examples
The Rational Number ClassThe Rational Number Classclass Rational {
public:
Rational(int top = 0, int bottom = 1}:
t(top), b(bottom) { normalize();}
// ...
private:
int t,b;
void normalize() // A private member function
{ if(b<0) {
b = -b;
t = -t;
}
int divisor = gcd(abs(t),b);
t /= divisor;
b /= divesor;
}
};
gcd defined elsewhere
A Unary Operator MemberA Unary Operator Memberclass Rational {
// ...
public:
// ...
Rational operator-() const
{ return Rational(-t,b);}
// ...
};
int main()
{
Rational r(-1,3);
Rational s = -r; // Activates r.operator-()
....
}
Arithmetic Operator MembersArithmetic Operator Membersclass Rational {
// ...
public:
// ...
Rational& operator+=(const Rational& r) const{
t = t*r.b+r.t*b;
b = b*r.b;
normalize();
return *this;
}
Rational& operator-=(const Rational& r) const{
t = t*r.b-r.t*b;
b = b*r.b;
normalize();
return *this;
}
};
Arithmetic Operator MembersArithmetic Operator Membersclass Rational {
// ...
public:
// ...
Rational& operator*=(const Rational& r) const{
t = t*r.t;
b = b*r.b;
normalize();
return *this;
}
Rational& operator/=(const Rational& r) const{
t = t*r.b;
b = b*r.t);
normalize();
return *this;
}
};
Symmetric OperatorsSymmetric Operatorsclass Rational {
// ...
public:
// ...
};
Rational operator+(const Rational& r1, const Rational& r2){...}
Rational operator-(const Rational& r1, const Rational& r2){...}
Rational operator*(const Rational& r1, const Rational& r2)
{
Rational tmp(r1);
return tmp*=r2;
}
friend Rational operator/(const Rational& r1, const Rational& r2){...}
Friends OperatorsFriends Operatorsclass Rational {
// ...
public:
// ...
friend bool operator==(const Rational&, const Rational&);
friend bool operator!=(const Rational&, const Rational&);
friend bool operator<=(const Rational&, const Rational&);
friend bool operator>=(const Rational&, const Rational&);
friend bool operator<(const Rational&, const Rational&);
friend bool operator>(const Rational&, const Rational&);
};
Not all of them need to be friend
Adding I/O to the Rational ClassAdding I/O to the Rational Classclass Rational {
public:
// ...
friend istream& operator>>(istream& in, Rational& r);
friend ostream& operator<<(ostream& out, Rational& r);
};
istream& operator>>(istream& in, Rational& r){
in >> r.t >> r.b;
return in;
}
ostream& operator<<(ostream& out, Rational& r){
out << r.t << '\' << r.b;
return out;
}
Using I/O in the Rational ClassUsing I/O in the Rational Class
int main(){
Rational r1(1,6), r2(1,3);
cout << r1 << '+' << r2 << '=' << r1+r2 << endl;
// will print: 1/6 + 1/3 = 1/2
return 0;}