Operator Overloading (1)
→ majority of c++ operators can be overloaded
→ except: :: , :? , .* , . , sizeof
Example
main.cpp:
#include <iostream>
#include "Mystring.h"
using namespace std;
int main() {
Mystring empty; // no-args constructor
Mystring larry{"Larry"} // overloaded constructor
Mystring stooge {larry}; // copy constructor
empty.display();
larry.display();
stooge.display();
return 0;
}
Mystring.h:
#indef _MYSTRING_H_
#define _MYSTRING_H_
class Mystring
{
private:
char *str; // pointer to char[] that holds a C-style string
public:
Mystring(); // No-args constructor
Mystring(const char *s); // Overloaded constructor
Mystring(const Mystring &source); // Copy constructor
~Mystring(); // Destructor
void display() const;
int get_length() const; // getters
const char *get_str() const;
};
#endif // _MYSTRING_H_
Mystring.cpp:
#include <cstring>
#include <iostream>
#include "Mystring.h"
// No-args construtor
Mystring::Mystring()
: str{nullptr} {
str = new char[1];
*str = '\0';
}
// overloaded constructor
Mystring::Mystring(const char *s)
:str {nullptr} {
if (s==nullptr) {
str = new char[1];
*str = '\0';
} else {
str = new char[std::strlen(s)+1];
std::strcpy(str,s)
}
}
// Copy constructor
Mystring::Mystring(const Mystring &source)
: str{nullptr} {
str = new char[std::strlen(source.str) + 1];
std::strcpy(str,source.str)
}
// Destructor
Mystring::~Mystring() {
delete [] str;
}
// Display method
void Mystring::display() const {
std::cout << str << ":" << get_length() << std::endl;
}
// length getter
int Mystring::get_length() const { return std::strlen(str); }
// string getter
const char *Mystring::get_str() const { return str; }
Overloading Copy assignment operator (deep copy)
Type &Type::operator=(const Type &rhs) // overloading the operator "="
Mystring &Mystring::operator=(constMystring &rhs);
s2 = s1; // We write this
s2.operator=(s1); // operator=method is called
// example 2 in Mystring.cpp file
Mystring &Mystring::operator=(const Mystring &rhs) {
if (this == &rhs)
return *this;
delete [] str;
str = new char[std::strlen(rhs.str) + 1];
std::strcpy(str, rhs.str);
return *this;
}
// -> Copy Assignment
Mystring &Mystring::operator=(const Mystring &rhs) {
std::cout << "Copy assignment" << std::endl;
if (this==&rhs)
return *this;
delete [] this->str;
str = new char [std::strlen(rhs.str) + 1];
std::strcpy(this->str, rhs.str);
return *this;
}
Overloading assignment operator (move)
// method in Mystring.h file
Mystring( Mystring &&source); // move constructor
Mystring &operator=(Mystring &&rhs); // move assignment
// Move constructor in Mystring.cpp file
Mystring::Mystring(Mystring &&source)
:str(source.str) {
source.str = nullptr;
std::cout << "Move constructor used" <<std::endl;
}
// Move assignment
Mystring &Mystring::operator=(Mystring &&rhs) {
std::cout << "Using move assignment" << std::endl;
if (this == &rhs)
return *this;
delete [] str;
str = rhs.str;
rhs.str = nullptr;
return *this;
}
Overloading operators as member functions
- using operator overloading and class declaration to make lowercase letters
- use of defined mystring operator
// // //
Mystring larry1 {"LARRY"};
Mystring larry2;
larry1.display(); // Larry
larry2 = -larry1; // larry1.operator-()
larry1.display(); // LARRY
larry2.display(); // larry
// // //
// creaty second object with lowercase version of the string
// create overloaded member function (operator)
Mystring Mystring::operator-() const{
char *buff = new char[std::strlen(str) + 1]; // new storage on the heap for the string
std::strcpy(buff, str);
for (size_t i=0; i<std::strlen(buff); i++)
buff[i] = std::tolower(buff[i]); // class function from cc-type header-file
Mystring temp {buff};
delete [] buff;
return temp;
}
Overloading Operators as Global Functions
// Make lowercase
bool operator==(const Mystring &lhs, const Mystring &rhs) { // two input arguments
return (std:strcmp(lhs.str, rhs.str) == 0);
}
// Concatenation
Mystring operator+(const Mystring &lhs, const Mystring &rhs) {
char *buff = new car[std::strlen(lhs.str) + std::strlen(rhs.str) + 1];
std::strcpy(buff, lhs.str);
std::strcat(buff, rhs.str);
Mystring temp {buff};
delete [] buff;
return temp;
}
stream insertion and extraction operators (<<,>>)
// stream insertion operator (<<)
std::ostream &operator<<(std::ostream &os, const Mystring &obj) {
os << obj.str; // if friend function
// os << obj.get_str(); // if not friend function
return os;
}
// Return a reference to the ostream so we can keep inserting
// Don't return ostream by value
// stream extraction operator (>>)
std::istream &operator>>(std::istream &is, Mystring &obj) {
char *buff = new char[1000];
is >> buff;
obj = Mystring{buff}; // If you have copy or move assignment
delete [] buff;
return is;
}
// Return a reference to the istream so we can keep inserting
// Update the object passed in
int main() {
Mystring larry {"Larry"};
Mystring moe {"Moe"};
Mystring curly;
cout << "Enter the third stooge's first name: ";
cin >> curly;
cout << "The three stooges are " << larry << ", " << moe << ", and" << curly << endl;
cout << "\nEnter the three stooges names separated by a space: ";
cin >> larry >> moe >> curly;
cout >> "The three stooges are " << larry << ", " << moe << ", and" << curly << endl;
return 0
}