目录
一、初识运算符重载
1.定义:赋予运算符具有操作自定义类型数据的功能
2.实质:函数调用
3.写法:函数返回值 函数名(函数参数)
● 函数返回值:运算完成后的值决定 ---->Complex
● 函 数 名:operator 加上重载运算符组成函数名----->operator+
● 参 数:看运算符的操作数,具体参数个数要看重载函数形式
● 函 数 体:写运算符具体想要的操作
二、友元函数和类成员函数重载运算符
#include<iostream>
#include<string>
using namespace std;
class Complex
{
public:
//缺省写法
Complex(int a = 0, int b = 0) :a(a), b(b){}
//友元函数运算符重载 --->参数个数就是操作数据
friend Complex operator+(Complex one, Complex two);
//类成员函数重载,参数个数等于操作减一
Complex operator-(Complex object)
{
return Complex(this->a - object.a, this->b - object.b);
}
void print()
{
cout << this->a << "\t" << this->b << endl;
}
protected:
int a;
int b;
};
//友元函数运算符重载 --->参数个数就是操作数据
Complex operator+(Complex one, Complex two)
{
return Complex(one.a + two.a, one.b + two.b);
}
int main()
{
Complex one(1, 2);
Complex two(2, 3);
//隐式调用
Complex three = one + two;//不做运算符重载无法相加
cout << "one:" << endl;
one.print(); //1 2
cout << "two:" << endl;
two.print(); //2 3
cout << "three:" << endl;
three.print(); //3 5
//显式调用
Complex four = one.operator-(two);
cout << "four:" << endl;
four.print(); //-1 -1
while (1);
return 0;
}
三、特殊运算符重载
1.流运算符重载
● cin类型:istream类的对象
● cout类型:ostream类的对象
● 流运算符 >> <<
注:必须采用友元函数形式重载
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person(string name="", int age=18): name(name), age(age){}
//重载流运算符
friend istream& operator>>(istream& in, Person& mm);
friend ostream& operator<<(ostream& out, Person& mm);
protected:
string name;
int age;
};
istream& operator>>(istream& in, Person& mm)
{
in >> mm.name >> mm.age;
return in;
}
ostream& operator<<(ostream& out, Person& mm)
{
out << mm.name << "\t" << mm.age << endl;
return out;
}
int main()
{
Person mm("Miss Du", 19);
Person gg("Mr Y", 20);
cout << mm << endl;
//因为需要连续输入输出,因此重载运算符应该返回输入输出流
//istream& operator>>(istream& in, Person& mm);
//ostream& operator<<(ostream& out, Person& mm);
cout << mm << endl << gg << endl;
while (1);
return 0;
}
2.++ --运算符重载
需解决的问题:前置和后置---->通过增加无用参数 int去表示当前运算符重载是后置操作
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person(string name = "", int age = 18) : name(name), age(age){}
//重载流运算符
friend istream& operator>>(istream& in, Person& mm)
{
in >> mm.name >> mm.age;
return in;
}
friend ostream& operator<<(ostream& out, Person& mm)
{
out << mm.name << "\t" << mm.age << endl;
return out;
}
Person operator++(int)//int无用参数,充当标记,表示后置运算
{
/*int num = age;
age++;
return MM(name, num);*/
//上面三行等效下面一行
return Person(name, age++);
}
Person operator++()//表示前置运算
{
return Person(name, ++age);
}
protected:
string name;
int age;
};
int main()
{
Person mm("Miss Du", 19);
cout << mm << endl;
Person mm2 = mm++;//mm2.age=19, mm.age=20;
//上面等同于下面
//Person mm2 = mm.operator++(1);
cout << mm2 << endl;
Person mm3 = mm.operator++();//等同于Person mm3=++mm;
cout << mm3 << endl;//mm3.age=21;
while (1);
return 0;
}
3.文本重载 (新标准中的,稍微落后一点开发工具不适用)
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
//文本重载
unsigned long long operator"" _h(unsigned long long num)
{
return 60 * 60*num;
}
unsigned long long operator"" _min(unsigned long long num)
{
return 60 * num;
}
int main()
{
//this_thread::sleep_for(3s);
cout << "3s结束" << endl;
int second = 1_h;
cout << second << "s" << endl;
int sum = 1_h + 18_min + 30;
cout << sum << "s" << endl;
while(1);
return 0;
}
4.其他运算符
● = () -> [] 只能采用类的成员函数形式重载
● 流重载采用友元方式
● . .* ?: :: 不能重载
5.对象隐式转换
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person(string name = "", int age = 18) : name(name), age(age){}
//类的对象的隐式转换 operator
operator int()
{
return age;
}
protected:
string name;
int age;
};
int main()
{
Person girl("Miss Du", 19);
int girlAge = girl;
cout << girlAge << endl;
while (1);
return 0;
}
四、重载综合案例(简单封装一个新的int类型)
#include<iostream>
#include<string>
using namespace std;
class Int
{
public:
Int(int num) :num(num){}
int& data()//引用
{
return num;
}
Int operator+(const Int& value)//加法
{
return Int(this->num + value.num);
}
//友元重载 :操作数-1 等于重载函数的参数个数
friend Int operator-(const Int& one,const Int&two)//减法
{
return Int(one.num - two.num);
}
//+=
Int operator+=(const int& object)//引用数据
{
return Int(this->num + object);
}
Int operator+=(const Int& object)//Int对象
{
return Int(this->num + object.num);
}
//++ --
Int operator++(int)
{
return Int(this->num++);
}
Int operator--()
{
return Int(--this->num);
}
//&运算
Int operator&(const Int& value)
{
return Int(this->num&value.num);
}
//取反
bool operator!()
{
return !this->num;
}
//负数
Int operator-()
{
return Int(-this->num);
}
//流重载
friend ostream& operator<<(ostream& out, const Int& object)
{
out << object.num << endl;
return out;
}
friend istream& operator>>(istream& in, Int& object)
{
in >> object.num;
return in;
}
//指针
int* operator&()
{
return &this->num;
}
//判断大小
bool operator>(const Int& object)
{
return this->num > object.num;
}
protected:
int num;
};
//重载[]
class myvector
{
public:
myvector(int size)
{
base = new int[size]{0};
}
int& operator[](int index)
{
return base[index];
}
protected:
int* base;
};
//重载()
class Function
{
typedef void(*PF)();
public:
Function(PF pf) :pf(pf) {}
void operator()()
{
pf();
}
protected:
PF pf;
};
void print()
{
cout << "测试函数" << endl;
}
int sum(int a, int b)
{
return a + b;
}
//->
struct MM
{
string name;
int age;
MM(string name, int age) :name(name), age(age) {}
};
class Auto_ptr
{
public:
Auto_ptr(int* ptr) :ptr(ptr) {}
Auto_ptr(MM* ptr) :ptrMM(ptr) {}
int& operator*()
{
return *ptr;
}
MM* operator->()
{
return ptrMM;
}
//手动写析构函数
~Auto_ptr()
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
if (ptrMM)
{
delete ptrMM;
ptrMM = nullptr;
}
}
protected:
int* ptr;
MM* ptrMM;
};
void testAuto_ptr()
{
Auto_ptr ptr(new int(18));
cout << *ptr << endl;
Auto_ptr ptrMM(new MM("mm", 19));
cout << ptrMM->name << endl;
cout << ptrMM->age << endl;
//先了解 需加 #include <memory>头文件
/*auto_ptr<int> autoPtr(new int(18));
cout << *autoPtr << endl;
auto_ptr<MM> autoPtrMM(new MM("mm", 19));
cout << autoPtrMM->name << endl;
cout << autoPtrMM->age << endl;*/
}
int main()
{
Int num(10);
cout << num << endl;
cout << -num << endl;
myvector vec(5);
for (int i = 0; i < 5; i++)
{
cin >> vec[i];
}
for (int i = 0; i < 5; i++)
{
cout << vec[i]<<" ";
}
Function p(print);
p();
//了解--->需加#include <functional>
//function<int(int,int)> pf(max);
//cout << pf(1, 2) << endl;
testAuto_ptr();
while (1);
return 0;
}
五、实战
● 封装一个Array类,实现定长数组的操作
//以下测试代码要能够成功运行
Array array(4);
for(int i=0;i<array.size();i++)
{
cin>>array[i];
}
for(int i=0;i<array.size();i++)
{
cout<<array[i];
}
//实现数组的连接
Array one(3); //输入1 2 3
cin>>one;
Array two(4); //输入2 3 4
cin>>two;
Array sum=one+two;
cout<<sum<<endl; //打印1 2 3 2 3 4
Array num;
num=sum;
cout<<num<<endl;
#include<iostream>
#include<string>
using namespace std;
class MyArray
{
public:
MyArray() = default;
MyArray(int size)
{
this->size = size;
base = new int[this->size];
}
int getSize()
{
return this->size;
}
int& operator[](int index)
{
return base[index];
}
friend ostream& operator<<(ostream& out, MyArray& object)
{
for (int i = 0; i < object.size; i++)
{
out << object.base[i];
}
return out;
}
friend istream& operator>>(istream& in, MyArray& object)
{
for (int i = 0; i < object.size; i++)
{
in >> object.base[i];
}
return in;
}
MyArray operator+(MyArray& object)
{
MyArray* temp = new MyArray(this->getSize() + object.getSize());
int j = 0;
for (int i = 0; i < this->size; i++)
{
temp->base[j++] = this->base[i];
}
for (int i = 0; i < object.size; i++)
{
temp->base[j++] = object.base[i];
}
return *temp;
}
MyArray(MyArray& object)
{
this->size = object.size;
this->base = new int[this->size];
for (int i = 0; i < this->size; i++)
{
this->base[i] = object.base[i];
}
}
~MyArray()
{
delete[]base;
}
protected:
int size;
int* base;
};
int main()
{
//以下测试代码要能够成功运行
MyArray array(4);
for (int i = 0; i<array.getSize(); i++)
{
cin >> array[i];
}
for (int i = 0; i<array.getSize(); i++)
{
cout << array[i];
}
cout << endl;
//实现数组的连接
MyArray one(3);
cin >> one;
MyArray two(4);
cin >> two;
MyArray sum = one + two;
cout << sum << endl;
MyArray num;
num = sum;
cout << num << endl;
while (1);
return 0;
}