-
运算符重载的本质是函数调用,只要参数不同,可以重载n次
-
函数参数相同,一个运算符只能被重载一次
class Int
{
public:
Int(int num) :num(num) {}
int& data()
{
return num; //获取数据
}
string tostr()
{
return to_string(num); //把int转换为string类型
}
//算术运算符重载
Int operator+(const Int& value) //+ 对象相加 类中成员函数重载的方式
{
return Int(this->num + value.num);
}
//友元重载: 操作数==重载函数的参数个数
friend Int operator-(const Int& one, const Int& two)
{
return Int(one.num - two.num);
}
Int operator+=(const int& value) //原来的值+=int类型的值
{
return Int(this->num + value);
}
Int operator+=(const Int& value) //原来的值+=一个对象 形成重载|参数类型不一致
{
return Int(this->num + value.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; //不需要返回对象,返回int*类型的地址即可
}
//关系运算符重载
bool operator>(const Int& object)
{
return this->num > object.num;
}
protected:
int num; //数据还是int类型
};
void print(const int& num)
{
cout << num << endl;
}
int main()
{
Int num(10);
cout << num;
cout << -num;
return 0;
}
/*输出*/
10
-10
重载[ ]
//重载[]运算符 只能采用类的成员函数重载 取值运算
class myvector
{
public:
myvector(int size)
{
base = new int[size] {0}; //new一段内存初始化为0
}
int& operator[](int index)
{
return base[index];
}
protected:
int *base; //内存存储数据||空间
};
int main()
{
myvector vec(5);
for (int i = 0; i < 5; i++)
{
cin >> vec[i];
}
for (int i = 0; i < 5; i++)
{
cout << vec[i];
}
}
/*输入*/
1 2 3 4 5
/*输出*/
12345
重载( ) - - - 类似函数包装器
//重载()运算符
class Function
{
typedef void(*PF)(); //定义一个函数指针
public:
Function(PF pf) :pf(pf) {} //把函数指针包装成一个对象,通过对象去调用函数
void operator()() //需要重载(),对象+()的方式充当调用函数的过程
{
pf();
}
protected:
PF pf; //以函数指针为参数的类
};
void print()
{
cout << "测试函数" << endl; //把print()的函数指针包装成一个对象
}
int main()
{
Function p(print); //构建一个对象,传入函数指针,可以通过p去调用函数
p();
return 0;
}
/*输出*/
测试函数
重载->
智能指针:自动管理内存,new完后不需要释放内存,对象消亡自动调用析构函数,做内存释放
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->() //返回ptrMM的地址(->: 单目运算符)
{
return ptrMM;
}
~Auto_ptr() //析构函数|智能指针可以自动申请&释放内存
{
if (ptr)
{
delete ptr; //ptr!=空做释放,对象在作用域结束后自己消亡
ptr = nullptr;
}
if (ptrMM)
{
delete ptrMM;
ptrMM = nullptr;
}
}
protected:
int* ptr; //管理int类型的指针
MM* ptrMM; //管理MM类型的指针
};
void testAuto_ptr()
{
//int* pInt = new int(18);
//Auto_ptr ptr(pInt);
//上面两行等效下面一行
Auto_ptr ptr(new int(18));
cout << *ptr << endl;
Auto_ptr ptrMM(new MM("mm", 19));
cout << ptrMM->name<< endl;
cout << ptrMM->age << endl;
#if 0
//标准库中的智能指针|模板
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;
#endif
}
int main()
{
testAuto_ptr();
}
/*输出*/
18
mm
19
为啥要加const修饰?
传引用时,为了传入变量和常量,通常加const修饰,避免传常量时类型不一致
void print(const int& num)
{
cout << num << endl;
}
int main()
{
print(1); //报错
int a=1;
print(a); //加const修饰,既可以传变量也可以传常量
}