目录
1、重载运算符定义
就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
比如实现对构造数据类型(类、结构体等)直接进行算术运算;
2、重载运算符一般表达式
声明成员重载运算符的一般表达式:
返回类型 operator@(参数表) //@代表运算符
{
重载函数体; //函数体代表实现这个运算符功能的程序源码
}
运算符重载为友元函数,在相应的类中声明为该类的友元函数,声明的一般形式为:
friend 返回类型 operator@(参数表)
{
函数体;
}
3、重载运算符的一般规定
可以重载的运算符 | 算术运算符 | +、-、*、\、%、++、-- |
位操作运算符 | &、|、~、^、>>、<< | |
逻辑运算符 | !、&&、|| | |
比较运算符 | <、>、>=、<=、==、!= | |
赋值运算符 | =、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= | |
其他运算符 | []、()、->、逗号、new、delete、new[]、delete[]、->* | |
不可以重载的运算符 | .、.*、?:、::、: 和sizeof、typeid、cast(4种) |
运算符实质上是一个函数,重载运算符就是重载一个函数,使用重载运算符之前要先定义这个重载运算符。其语法就和定义一个函数一样。重载运算符时不能改变运算符操作数的个数、原有的优先级、结合性和语法规则。
4、几种常见的重载运算符
(1)、重载:+、++前置、++后置、=赋值号
/*重载运算符+、++、= */
/*运算符实际上是一个函数,运算符重载是函数的重载*/
/*两种方法实现两个类对象的加法运算:成员函数、重载运算符*/
/*重载运算符后,可以完成对象和对象之间的运算,也可以通过重载运算实现对象和普通数据类型的运算*/
#include <iostream>
using namespace std;
class CBook
{
public:
CBook()
{
m_iPage = 0;
}
CBook(int iPage) //定义一个带参的构造函数,把整型数据赋值给对象
{
m_iPage = iPage;
}
CBook operator+(CBook b) //定义重载运算符+
{
return CBook(m_iPage + b.m_iPage);//执行构造函数CBook(),实参是m_iPage + b.m_iPage,执行后m_iPage=m_iPage + b.m_iPage,加法
}
CBook operator+(const int page) //定义重载运算符+
{
CBook bk; //定义对象
bk.m_iPage = m_iPage + page;
return bk;
}
CBook operator++() //定义重载++前置运算符,没有参数
{
return ++m_iPage;
}
CBook operator++(int) //定义重载++后置运算符,带整型参数,参数可忽略
{
return m_iPage++;
}
operator double() //定义重载转换运算符,把类的对象转换为double
{
return m_iPage;
}
void operator=(int page) //通过重载运算符把一个整数赋值给一个对象,该函数可有可无
{
m_iPage = page;
}
int add(CBook a) //定义+函数
{
return (m_iPage + a.m_iPage);
}
void display()
{
cout << m_iPage << endl;
}
protected:
int m_iPage;
};
int main()
{
CBook bk1(10);
CBook bk2(20);
CBook tmp1(0);
tmp1= bk1+bk2; //当注释掉重载运算符+后,警告 E0349,
tmp1.display();
CBook tmp2(0);
tmp2 = bk1.add(bk2); //bk1.add()的参数是bk2
tmp2.display();
cout << bk1.add(bk2) << endl;
bk2 = bk1 + 10;
bk2.display();
++bk2;
bk2.display();
bk2++;
bk2.display();
bk2 = 20;
bk2.display();
cout << "bk1+bk2=" << double(bk1)+double(bk2) << endl;
}
/*运行结果:
30
30
30
20
21
22
20
bk1+bk2=30 */
(2)、重载:<<和>>
<<和>>只能通过全局函数配合友元函数进行重载;
/*重载输入和输出流运算符<<>>*/
#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
private://私有变量 重载时必须加上friend
double m_real;
double m_imag;
public:
Complex(double real = 0.0, double imag = 0.0) :m_real(real), m_imag(imag)
{};
public:
friend Complex operator +(const Complex& a, const Complex& b);
friend istream& operator >>(istream& pt, Complex& a);
friend ostream& operator <<(ostream& out, Complex& a);
};
Complex operator +(const Complex& a, const Complex& b)
{
Complex c;
c.m_real = a.m_real + b.m_real;
c.m_imag = a.m_imag + b.m_imag;
return c;
}
istream& operator >>(istream& in, Complex& a)
{
in >> a.m_real >> a.m_imag;
return in;
}
ostream& operator <<(ostream& out, Complex& a)
{
out << a.m_real << "+" << a.m_imag << "i";
return out;
}
int main()
{
Complex c1, c2, c3;
cout << "输入c1和c2:" << endl;
cin >> c1 >> c2;
c3 = c1 + c2;
cout << "c3=" << c3 << endl;
return 0;
}
/*运行结果:
输入c1和c2:
34 68
12 48
c3=46+116i */
(3)、重载:()
/*重载()*/
#include<iostream>
using namespace std;
class Distance
{
private:
int feet;
int inches;
public:
Distance()
{
feet = 0;
inches = 0;
}
Distance(int f, int i) :feet(f), inches(i)
{}
Distance operator ()(int a, int b, int c)
{
Distance ob;
ob.feet = a + c + 20;
ob.inches = b + c + 200;
return ob;
}
void showDistance()
{
cout << "F=" << feet << "I=" << inches << endl;
}
};
int main()
{
Distance D1(12, 20), D2;
cout << "第一个是:";
D1.showDistance();
D2 = D1(10, 20, 30);
cout << "第二个是:";
D2.showDistance();
return 0;
}
/*运行结果:
第一个是:F=12I=20
第二个是:F=60I=250 *//*重载()*/
#include<iostream>
using namespace std;
class Distance
{
private:
int feet;
int inches;
public:
Distance()
{
feet = 0;
inches = 0;
}
Distance(int f, int i) :feet(f), inches(i)
{}
Distance operator ()(int a, int b, int c)
{
Distance ob;
ob.feet = a + c + 20;
ob.inches = b + c + 200;
return ob;
}
void showDistance()
{
cout << "F=" << feet << "I=" << inches << endl;
}
};
int main()
{
Distance D1(12, 20), D2;
cout << "第一个是:";
D1.showDistance();
D2 = D1(10, 20, 30);
cout << "第二个是:";
D2.showDistance();
return 0;
}
/*运行结果:
第一个是:F=12I=20
第二个是:F=60I=250 */
(4)、重载:[]
/*重载[]下标运算符*/
#include <iostream>
using namespace std;
class Data
{
private:
int m_length;
int* m_p;
public:
Data(int length = 0);
~Data();
int& operator [](int i);
const int& operator [](int i)const;
int length()const { return m_length; }
void display()const;
};
Data::Data(int length) :m_length(length)
{
if (length == 0)
m_p = NULL;
else
m_p = new int[length];
}
Data::~Data()
{
delete[] m_p;
}
int& Data::operator [](int i)
{
return m_p[i];
}
const int& Data::operator [](int i)const
{
return m_p[i];
}
void Data::display()const
{
for (int i = 0; i < m_length; i++)
{
if (i == m_length - 1)
cout << m_p[i] << endl;
else
cout << m_p[i] << ", ";
}
}
int main()
{
int n;
cin >> n;
Data ob(n);
for (int i = 0, len = ob.length(); i < len; i++)
{
ob[i] = i * 5;
}
ob.display();
const Data pt(n);
cout << pt[n - 1] << endl;
return 0;
}
/*运行结果:
4
0, 5, 10, 15
-842150451 */
(5)、重载:--前置、--后置
/*重载--*/
#include <iostream>
using namespace std;
class Data
{
private:
int a=0;
public:
Data()//默认构造函数
{
}
Data(int a)
{
this->a = a;
}
void display()
{
cout << "a=" << a << endl;
}
Data operator --()//前缀--
{
Data temp;
temp.a = --a;
return temp;
}
Data operator --(int)//后缀--
{
Data ob;
ob.a = a--;
return ob;
}
};
int main()
{
Data D1(11), D2(10);
--D1;
D1.display();
--D1;
D1.display();
D2--;
D2.display();
D2--;
D2.display();
return 0;
}
/*运行结果:
a=10
a=9
a=9
a=8 */
(6)、重载:+=
/*重载的+=*/
#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
public://构造函数,类中有2个double型的数据成员
Complex(double real = 0.0, double imag = 0.0) : m_real(real), m_imag(imag) { } //构造函数后:初始化表达式
public://以全局函数的形式重载
friend Complex operator+(const Complex &c1, const Complex &c2);
Complex &operator+=(const Complex &c); //成员函数重载
public://成员函数
double real() const { return m_real; }
double imag() const { return m_imag; }
private:
double m_real;
double m_imag;
};
//重载+运算符
Complex operator+(const Complex& c1, const Complex& c2)
{
Complex c;
c.m_real = c1.m_real + c2.m_real;
c.m_imag = c1.m_imag + c2.m_imag;
return c;
}
//重载+=运算符
Complex& Complex::operator+=(const Complex& c)
{
this->m_real += c.m_real;
this->m_imag += c.m_imag;
return *this;
}
int main()
{
Complex c1(20, 30); //定义了3个类对象,各自2个数据成员
Complex c2(10, 20);
Complex c3(36, 9);
Complex c7 = c1 + c2;
cout << "c7 = " << c7.real() << " + " << c7.imag() << "i" << endl;
c3 += c1;
cout << "c3 = " << c3.real() << " + " << c3.imag() << "i" << endl;
return 0;
}
/*运行结果:
c7 = 30 + 50i
c3 = 56 + 39i */
(7)、重载:=(复制运算符)
这里的“=”不是赋值号而是复制拷贝函数的复制运算符;
例一:
/*重载=复制拷贝函数运算符*/
#include<iostream>
#include<string.h>
using namespace std;
class CBook
{
private:
char* book_name{NULL}; //指针成员变量
public:
CBook() //默认构造函数
{
book_name = NULL;
}
CBook(char* book_name)//重载的构造函数
{
this->book_name = new char[strlen(book_name) + 1]; //根据实参数strlen,给this->book_name申请空间
strcpy_s(this->book_name, strlen(book_name) + 1, book_name);//复制
}
CBook(const CBook& book)//复制构造函数,调用自身类的对象,CBook& book代表旧对象
{
this->book_name = new char[strlen(book.book_name) + 1]; //this->book_name,新构造函数的对象
strcpy_s(this->book_name, strlen(book.book_name) + 1, book.book_name);//复制book.name
}
~CBook()
{
if (this->book_name != NULL)
delete[] this->book_name;
this->book_name = NULL;
}
void showPerson()
{
cout << "book_name=" << book_name << endl;
}
CBook& operator =(CBook& book) //重载=
{
if (this->book_name != NULL) //表明this->book_name以前有指向
{
delete[] this->book_name;
this->book_name = NULL;
this->book_name = new char[strlen(book.book_name) + 1]; //申请空间
strcpy_s(this->book_name, strlen(book.book_name) + 1,book.book_name);
return *this;
}
}
};
int main()
{
char* name1;
name1 =(char*) "詹姆斯";
CBook book1(name1);
book1.showPerson();
CBook book2 = book1; //调用拷贝构造,book2复制book1
book2.showPerson();
char* name2;
name2 = (char*)"邦德";
CBook book3(name2);
book3.showPerson();
book3 = book1; //调用拷贝构造,book3复制book1
book3.showPerson();
}
/*运行结果:
book_name=詹姆斯
book_name=詹姆斯
book_name=邦德
book_name=詹姆斯 */
例二(对比不用重载运算符的复制拷贝函数):
/*重载=,复制运算符*/
#include<iostream>
using namespace std;
class CBook
{
private:
int temp_a;
int temp_b;
public:
CBook()
{
temp_a = 0;
temp_b = 0;
}
CBook(int temp_a, int temp_b) :temp_a(temp_a), temp_b(temp_b)
{}
void showPerson()
{
cout << "temp_a=" << temp_a << ",temp_b=" << temp_b << endl;
}
~CBook()
{
}
};
int main()
{
CBook book1(10, 20);
book1.showPerson();
CBook book2 = book1; //不是调用赋值运算符
book2.showPerson();
CBook book3;
book3 = book1; //复制拷贝函数
book3.showPerson();
}
/*运行结果:
temp_a=10,temp_b=20
temp_a=10,temp_b=20
temp_a=10,temp_b=20 */