运算符的重载
有以下几个部分
- “+”号运算符的重载。
- 左移运算符的重载。
- 递增运算符的重载。
- 赋值运算符的重载。
- 关系运算符的重载。
- 函数调用运算符重载。
首先什么是运算符的重载:
就是对已有的运算符赋予多重含义,使得同一个运算符作用于不同类型的数据导致不同的行为。
operator+ 运算符函数
接下来看着这个案例
在#include<iostream>
using namespace std;
class Person{ //声明类Person
public:
Person(double r=0.0,double i=0.0);
friend Person operator+(Person& a,Person& b);
void display();
private:
double real;
double imag;
};
Person::Person(double r,double i)
{
real=r;imag=i;
}
Person operator+(Person& a,Person& b)
{
Person t;
t.real=a.real+.real;
t.imag=a.imag+b.imag;
return t;
}
void Person::display()
{
cout<<real;
if(imag>0) cout<<"+";
if(imag!=0) cout<<imag<<"i\n";
}
int main()
{
Person A(2.3,4.6),B(3.2,2.6),C; //定义3个复数类对象
A.display(); //输出A
B.display(); //输出B
C=A+B; //复数相加
C.display() ; //输出相机的结果C
C=operrator+(A,B);
C.display() ; //输出相机的结果C
return 0;
}
我们知道如何将两个数相加,同样的C++能直接让int型或者float类型相加,但是让两个类对象Person相加,不能直接相加,这时候需要通过重载" + "来进行实现。
使用重载“+”后计算变得简洁了,c++提供了一种方法,即在进行函数重载时候,必须写一个 operator 后跟随一个 要重载的运算符,就如上面的案例一样,
重载“+”,写一个”operator+“的函数,
运算符重载函数
函数 | 功能 |
---|---|
operator+() | 加法 |
operator-() | 减法 |
operator*() | 乘法 |
operator/() | 除法 |
operator<() | 小于 |
赋值 "=="运算符重载
"++"作为单目运算符,成员运算符重载函数的参数表中没有参数,此时当前对象的一个操作数,
#include<iostream>
#include<string>
using namespace std;
class Person {
public:
Person(string name, int age)
{
this->m_Name = name; //由对象this隐含的传递
this->m_Age = age;
};
bool operator == (Person & p)
{
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
{
return true;
}
return false;
}
string m_Name;
int m_Age;
};
void test01()
{
//int a=0;
//int b=0;
Person a("詹姆斯", 18);
Person b("詹姆斯", 18);
if (a == b)
{
cout << "a和b相等" << endl;
}
else
{
cout << "a和b不相等" << endl;
}
}
int main()
{
test01();
system("pause");
}
左移运算符的重载
class Person{
friend ostream& operator<<(ostream& out,person& p);
public:
Person(int a,int b)
{
this->m_A=a;
this->m_B=b;
}
//成员函数 实现不了 p<<cout 不是我们想要的效果
// void operator<<(PErson& p){}
private:
int m_A;
int m_B;
};
//全局函数实现左移重载
// ostream对象只能有一个
ostream& operator<<(ostream& out,Person& p){
out <<"a:"<<p.m_A<<"b:"<<p.m_B;
return out;
}
void test()
{
Person p1(10,20);
cout << p1<<"hello world" <<endl; //链式编程
}
int main(){
test();
system("pause");
return 0;
}
函数调用的重载
#include<iostream>
#include<string>
using namespace std;
class Myprint{
public:
void operator()(string test)
{
cout << test << endl;
}
};
void test01()
{
Myprint myprint;
myprint("hello world");
}
int main() {
test01();
//test02();//
system("pause");
return 0;
}
运算符函数重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。非成员函数通常是友元。(可以把一个运算符作为一个非成员、非友元函数重载。但是,这样的运算符函数访问类的私有和保护成员时,必须使用类的公有接口中提供的设置数据和读取数据的函数,调用这些函数时会降低性能。可以内联这些函数以提高性能。)
1) 成员函数运算符
运算符重载为类的成员函数的一般格式为:
<函数类型> operator <运算符>(<参数表>)
{
<函数体>
}
当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后置单目运算符除外),这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。因此:
(1) 双目运算符重载为类的成员函数时,函数只显式说明一个参数,该形参是运算符的右操作数。
(2) 前置单目运算符重载为类的成员函数时,不需要显式说明参数,即函数没有形参。
(3) 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。
调用成员函数运算符的格式如下:
<对象名>.operator <运算符>(<参数>)
它等价于
<对象名><运算符><参数>
例如:a+b等价于a.operator +(b)。一般情况下,我们采用运算符的习惯表达方式。
2) 友元函数运算符
运算符重载为类的友元函数的一般格式为:
friend <函数类型> operator <运算符>(<参数表>)
{
<函数体>
}
当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。
调用友元函数运算符的格式如下:
operator <运算符>(<参数1>,<参数2>)
它等价于
<参数1><运算符><参数2>
例如:a+b等价于operator +(a,b)。
两种重载形式的比较
在多数情况下,将运算符重载为类的成员函数和类的友元函数都是可以的。但成员函数运算符与友元函数运算符也具有各自的一些特点:
(1) 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。
(2) 以下一些双目运算符不能重载为类的友元函数:=、()、[]、->。
(3) 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。
(4) 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
(5) 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
(6) 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个友元函数来实现。
(7) 当需要重载运算符具有可交换性时,选择重载为友元函数。