Chapter 8, Overloading * const parameters, const member functions // Prevents you from changing a and b int add(const int a, const int b) { return a + b; } // Prevents you from changing any member variables in that member function class Integer { private: int a; public: int add(const int b) const; int sub(const int b) const; ... }; int Integer::add(const int b) const { return a + b; } * Operator overloading class Integer { private: int a; public: Integer(int i); void output() const; void input(); const Integer operator +(const Integer& i) const; const Integer operator -(const Integer& i) const; bool operator ==(const Integer& i) const; const Integer operator -() const; }; Integer::Integer(int i) { a = i; } void Integer::output() const { cout << a; } void Integer::input() { cin >> a; } const Integer Integer::operator +(const Integer& i) const { return Integer(a + i.a); } const Integer Integer::operator -(const Integer& i) const { return Integer(a - i.a); } bool Integer::operator ==(const Integer& i) const { return a == i.a; } const Integer Integer::operator -() const { return Integer(-a); } The object for which the operator function is called is the left one, for a binary operator. The left variable is the argument to the function. Integer i(10), j(20), k(0); k = i + j; // k = i.+(j); Using constructors for automatic type conversion: Integer i(10), j(0); j = i + 25; 25 is an integer, but it uses your constructor that takes in an int to convert it to an Integer. But what about: j = 25 + i; // error! How do you fix this? Unmemberize the operator functions. class Integer { private: int a; public: Integer(int i); int getInteger() const; void output() const; void input(); const Integer operator -() const; }; int getInteger() const { return a; } const Integer operator +(const Integer& i1, const Integer& i2) { return Integer(i1.getInteger() + i2.getInteger()); } Requiring getters and setters is annoying and slow. Use friend functions. When you friend a function in a class, that function can access private members. class Integer { private: int a; public: Integer(int i); void output() const; void input(); const Integer operator -() const; friend const Integer operator +(const Integer& i1, const Integer& i2); friend const Integer operator -(const Integer& i1, const Integer& i2); friend bool operator ==(const Integer& i1, const Integer& i2); }; const Integer operator +(const Integer& i1, const Integer& i2) { return Integer(i1.a + i2.a); } const Integer operator -(const Integer& i) const { return Integer(-(i.a)); } String class with operator overloading: class MyString { private: int len; char *s; public: MyString(char *str); MyString(const MyString& str); MyString& operator =(const MyString& str); MyString& operator =(const char *str); char& operator[](int index); friend const MyString operator +(const MyString& s1, const MyString& s2); friend const bool operator ==(const MyString& s1, const MyString& s2); friend ostream& operator <<(ostream& os, const MyString& str); friend istream& operator >>(istream& is, MyString& str); }; MyString::MyString(char *str) { ... } MyString::MyString(const MyString& str) { // Do same as above on str.s } MyString& MyString::operator =(const MyString& str) { // Do same as above on str.s return *this; } MyString& MyString::operator =(const char *s) { // Do same as above on s return *this; } char& MyString::operator[](int index) { if(index >= 0 && index < len); return s[index]; else { cout << "Illegal index" << endl; exit(0); } } const MyString operator +(const MyString& s1, const MyString& s2) { // do strcat on s1.s and s2.s } const bool operator ==(const MyString& s1, const MyString& s2) { // do strcmp on s1.s and s2.s } ostream& operator <<(ostream& os, const MyString& str) { os << s2.s; return os; } istream& operator <<(istream& os, const MyString& str) { is >> s2.s; return is; } int main() { MyString s1("hello"), s2("goodbye"); MyString s3 = s1 + s2; cout << s3; if(s1 == s2) { cout << "This should not print"; } s1[0] = 'j'; cin >> s2; if(s1 == s2) { cout << "You must have said jello"; } return 0; }