2、分析运算符左边的运算对象:自定义对象还是其他,这个就决定了我们是使用全局函数还是成员函数。
左边是其他:使用全局函数(声明为有元)
左边是自定义的对象:可以使用全局函数也可以使用成员函数(推荐,因为只用一个参数)。
2、重载输出<<运算符:
时机:cout<<实例化自定义对象
//重载<<运算符 ,cout<<对象的时候会出现
//左边是其他函数不是自定义函数,在全局区。
#include
#include
using namespace std;
class person
{
friend ostream &operator<<(ostream &cout,person &ob);
private:
int age;
int num;
public:
person(){}
person(int a,int n):age(a),num(n){}
//使用初始化列表
};
//返回值类型是ostream类型的引用,俩个参数一个cout,一个对象
ostream &operator<<(ostream &cout,person &ob)
{
cout<
3、重载输入>>运算符:
#include
using namespace std;
class Person
{
friend istream &operator >>(istream &in, Person &ob);
private:
int age;
int num;
public:
Person() {}
Person(int a, int n):age(a), num(n){}
};
//重载>>运算符
istream &operator >>(istream &in, Person &ob)
{
in >> ob.age >> ob.num;
return in;
}
void test02()
{
Person lucy;
cin >> lucy;
cout << lucy;//这个地方需要重载一个<<运算符
}
int main(int argc, char *argv[])
{
test02();
return 0;
}
4、重载+运算符:
例1:利用全局函数实现+运算符重载
//+运算符在全局重载
#include
using namespace std;
class Person
{
friend Person operator+(const Person &p1,const Person &p2);
friend ostream &operator <<(ostream &cout,const Person &p);
private:
int num;
public:
Person() {}
Person( int n):num(n){}
};
ostream &operator <<(ostream &cout,const Person &p)
{
cout<
例2:利用成员函数实现+运算符重载
//+运算符在全局重载
#include
using namespace std;
class Person
{
friend ostream &operator <<(ostream &cout,const Person &p);
private:
int num;
public:
Person() {}
Person( int n):num(n){}
Person operator+(const Person &p2)
{
Person temp;
temp =this->num+p2.num;
return temp;
}
};
ostream &operator <<(ostream &cout,const Person &p)
{
cout<
5、重载==运算符:
//==重载,返回一个bool类型
#include
using namespace std;
class Person
{
private:
int age;
int num;
public:
Person() {}
Person( int a,int n):age(a),num(n){}
bool operator ==(const Person &p2)
{
if(this->age == p2.age && this->num == p2.num)
return true;
else
{
return false;
}
}
};
void test01()
{
Person p1(10,20);
Person p2(20,10);
if(p1 == p2)
{
cout<<"相等"<
6、重载--运算符:
//--重载
//前置--没有参数,后置--有个int参数
#include
using namespace std;
class Person
{
friend ostream& operator<<(ostream& cout, const Person& p);
private:
int age;
public:
Person() {}
Person(int a):age(a){}
Person operator--()
{
Person temp;
temp.age = age-1;
return temp;
}
Person operator--(int)
{
Person temp = *this;
temp.age = age -1;
return temp;
}
};
ostream& operator<<(ostream& cout, const Person& p)
{
cout << p.age << endl;
return cout;
}
void test01()
{
Person p1(10);
cout<<--p1<
7、重载++运算符:
//++重载
//前置++没有参数,后置++有个占位参数
#include
using namespace std;
class Person
{
friend ostream& operator<<(ostream& cout, const Person& p);
private:
int age;
int num;
public:
Person() {}
Person(int a,int num):age(a),num(num){}
Person operator++()
{
Person temp;
temp.age = age + 1;
temp.num = num + 1;
return temp;
}
Person operator++(int)
{
Person temp = *this;
temp.age = age + 1;
temp.num = num + 1;
return temp;
}
};
ostream& operator<<(ostream& cout, const Person& p)
{
cout << p.age <<" "<
8、重载&& || 运算符:
建议不要重载,会破坏短路特性
在C++中&&和||具有短路特性,即在条件判断中,如果能够根据左值来确定整个表达式的结果,则不会执行右侧的条件判断。
重载运算符之后破坏了短路性,因为重载之后的运算符函数必须始终被调用,无论左值是否为真,这意味着无法绕过右侧的条件判断,导致无法实现原有的短路性为。
9、重载函数调用运算符(函数名()):
为算法提供相关策略。
//函数名()重载
#include
using namespace std;
class Person
{
public:
Person() {}
Person &operator()(const char* str)
{
cout << str << endl;
//返回值是引用,因为是对原来的实例化对象改变
}
};
void test01()
{
Person p1;
p1("hello");
//需要重载(),p1虽然是个对象但是可以当初仿函数。
}
int main(int argc, char *argv[])
{
test01();
return 0;
}
10、符号重载的总结:
1、=, [ ], ( ) 和 -> 操作符只能通过成员函数进行重载。 |
2、>>和<<只能通过全局函数配合友元函数进行重载(在类中声明友元函数)。 |
3、不要重载 && 和 || 操作符,因为无法实现短路规则 |
运算符 |
建议使用 |
所有的一元运算符 |
成员 |
=, [], () 和 -> |
必须是成员 |
其他的二元运算符 |
非成员 |
11、string字符串类的封装 :
mystring.h
#ifndef MY_STRING_H
#define MY_STRING_H
#include
//#include
using namespace std;
class MyString
{
friend ostream & operator<<(ostream &out, MyString ob);
friend istream & operator>>(istream &in, MyString &ob);
private:
char *str;
int size;
public:
MyString();
explicit MyString(const char * s);
MyString(const MyString &ob);
~MyString();
Size();
char & operator[](int index);
MyString & operator=(MyString ob);
MyString & operator=(const char * s);
MyString operator+(MyString &ob);
MyString operator+(const char * s);
bool operator>(MyString &ob);
bool operator>(const char * s);
};
#endif // MY_STRING_H
mystring.cpp
#include "mystring.h"
#include
MyString::MyString()
{
str = new char[0];
size = 0;
}
MyString::MyString(const char *s)
{
// cout << "MyString 有参构造" << endl;
size = strlen(s);
str = new char[size + 1];
strcpy(str, s);
}
MyString::MyString(const MyString &ob)
{
// cout << "MyString 拷贝构造" << endl;
size = ob.size;
str = new char[size + 1];
strcpy(str, ob.str);
}
MyString::~MyString()
{
if(str != NULL){
delete [] str;
str = NULL;
}
}
MyString::Size()
{
return this->size;
}
char &MyString::operator[](int index)
{
return str[index];
}
MyString &MyString::operator=(MyString ob)
{
if(str != NULL)
{
delete [] str;
str = NULL;
}
size = ob.size;
str = new char[size + 1];
strcpy(str, ob.str);
return *this;
}
MyString &MyString::operator=(const char *s)
{
if(str != NULL)
{
delete [] str;
str = NULL;
}
size = strlen(s);
str = new char[size + 1];
strcpy(str, s);
return *this;
}
MyString MyString::operator+(MyString &ob)
{
MyString tmp;
tmp.size = size + ob.size;
tmp.str = new char[tmp.size];
strcpy(tmp.str, str);
strcat(tmp.str, ob.str);
return tmp;
}
MyString MyString::operator+(const char *s)
{
MyString tmp;
tmp.size = size + strlen(s);
tmp.str = new char[tmp.size];
strcpy(tmp.str, str);
strcat(tmp.str, s);
return tmp;
}
bool MyString::operator>(MyString &ob)
{
if((strcmp(str, ob.str)) > 0)
return true;
else
return false;
}
bool MyString::operator>(const char *s)
{
if((strcmp(str, s)) > 0)
return true;
else
return false;
}
ostream & operator<<(ostream &out, MyString ob)
{
out << ob.str;
return out;
}
istream & operator>>(istream &in, MyString &ob)
{
if(ob.str != NULL){
delete [] ob.str;
ob.str = NULL;
}
char buf[1024] = {0};
in >> buf;
ob.size = strlen(buf);
ob.str = new char[ob.size + 1];
strcpy(ob.str, buf);
return in;
}
main.cpp
#include
#include
using namespace std;
int main(int argc, char *argv[])
{
MyString str("hello world");
//有参构造
cout << str << endl;
cout << str.Size() << endl;
//重载<<
MyString str1 = str;
//重载等号
cout << str1 << endl;
MyString str2;
cin >> str2;
//重载>>
str2[1] = 'E';
cout << str2[1] << endl;
cout << str2 << endl;
MyString str3;
MyString str4("haha hehe");
str3 = str4;
cout << str3 << endl;
MyString str5;
str5 = "xixi heihei";
cout << str5 << endl;
MyString str6("hello");
MyString str7("hihi");
cout << str6 + str7 << endl;
cout << str6 + "world" << endl;
MyString str8("hello");
MyString str9("world");
if(str8 > str9){
cout << "hello大于world";
}
else
cout << "world比hello大";
if(str9 > "haha")
cout << "hello大" << endl;
else
cout << "haha大" << endl;
return 0;
}