一、为什么要运算符重载
C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。
利用 C++ 提供的“运算符重载”,赋予运算符新的功能,就能解决用+将两个对象相加这样的问题
运算符重载基本格式:
返回值类型 operator 运算符(形参表)
{
...
}
二、赋值(=)运算符重载
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
class Int
{
private:
int value;
public:
//构造函数
Int(int x) :value(x)
{
}
//析构函数
~Int()
{
cout << "destroy obj" << " " << this << endl;
}
//拷贝构造函数
Int(const Int& it) :value(it.value)
{
cout << "copy cerate obj" << " " << "val= " << value << " " << this << endl;
}
//=运算符重载
Int& operator =(const Int& x)
{
if (this != &x)
{
this->value = x.value;
}
return *this;
}
void Print()
{
cout << "value=" <<value<< endl;
}
};
int main()
{
Int a(10);
Int b(20);
Int c(30);
a = b;
a.Print();
}
1、理解:为什么这么设计
operator函数实际形参为:
void operator = (Int * const this , const Int &x)
(1)a = a
实际是a=a.operator() operator=(&a,a)
a的地址给this指针,a给x初始值
所以进行if语句,防止自己给自己赋值
(2)a=b=c
实际是a=operator=(&b,c)
b的地址给this指针,c初始化ix
所以返回*this,从而实现连续赋值
因为函数调用结束,b依然在,所以可以返回引用,用了引用不会在函数内部创建一个副本
三、加号+运算符重载
#include<stdio.h>
#include<iostream>
using namespace std;
class Int
{
private:
int value;
public:
Int(int x) :value(x)
{
}
~Int()
{
}
//+号运算符重载,实现对象+对象
Int operator +(const Int& x)
{
return Int(this->value + x.value);
}
//+运算符重载,实现对象+常量
Int operator +(int x)
{
return Int(this->value + x);
}
void Print()
{
cout << "value=" << value << endl;
}
};
int main()
{
Int a(10);
Int b(20);
a = a + b;
a.Print();
Int c(10);
int x = 10; //对象+对象
c = a + 10; //对象+常量
c.Print();
}
的:实现对象与对象相加,对象与变量相加
四、前置++、后置++重载
//前置++ 先+1再赋值
Int & operator++()
{
this->value += 1;
return *this;
}
//后置++ 先赋值再++
Int & operator++(int)
{
Int tmp(this->value++);
return tmp;
}
};
为区分前置++后置++ ,给后置++加上int ,实际不算参数
注意:再for 循环中
//常见写法
for(int i=0;i<10;i++)
{
cout<<i<<endl;
}
//如果将int 换成Int 即把i变成一个对象 ,那么运行时会一直连续创建10个对象,占用内存
//正确写法
for(Int i=0;i<10;++i)
{
cout<<i<<endl;
}
五、强转类型重载
//类型强转重载
operator int() const
{
return value;
}
};
int main()
{
Int a(10);
Int b(20);
cout << (a < b) << endl;//程序结果为1
cout << (a == b) << endl;//结果为0
}
理解:
1、类型强转无返回值
2、再C语言或者c++中,只有内置类型可进行大小,等于,不等于比较,对强转函数进行重载后,对象与对象比较,会把对象强转为内置类型进行比较; 对象与常量比较,会把对象转化为对应类型后,再进行比较
3、强转函数重载后,一个函数即可完成 > < == != 等运算符,不必再写其他运算符重载
六、输出流<<运算符重载
为什么对其重载?
以下程序,最后一行代码cout<<a;是错误的
class Int
{
private:
int value;
public:
Int(int x) :value(x){}
~Int(){}
void Print()
{
cout << "value=" << value << endl;
}
};
int main()
{
Int a(10);
Int b(20);
cout << a;
正确的做法是要对输出运算符 << 进行重载。那么运算符重载有两种方式——成员函数和全局函数,这里该用哪种呢?
答案是全局函数,为什么?
因为ostream本身是一个类,如重载成员函数,cout << p 就应该等价于cout.operator<<p
cout属于ostream类,相当于对类进行修改
正确写法:
#include<stdio.h>
#include<iostream>
using namespace std;
class Int
{
private:
int value;
public:
Int(int x) :value(x){}
~Int(){}
friend ostream& operator<<(ostream& out, const Int& x); //声名友元
};
// <<重载
ostream & operator<<(ostream & out, const Int& x) //第一个参数传cout(标准输出),第二个传类的对象
{
cout << x.value << endl;
return out;
}
int main()
{
Int a(10);
Int b(20);
cout << a << b;
}