C++运算符重载——重载二元运算符

1、重载二元操作符的方法


二元运算符又称为双目运算符,即需要2个操作数的运算符,例如 + - * /
等。

运算符重载可以分为3种方式:类的非静态成员函数、类的友元函数、普通函数。

例如有 2 个操作数 a 和 b,二元运算符 ?
(表示一个二元运算符),a ? b 的操作会被解释为下面2种形式之一

//a ? b
a.operator?(b); //类的非静态成员函数
operator(a, b); //友元函数 和 普通函数

第一种形式是运算符被重载为类的非静态成员函数,

这种方式要求运算符左边的的操作数(即第一个操作数a)必须是一个对象,operator?是这个对象的非静态成员函数

并且只能有一个参数。

第二种形式是运算符被重载为类的友元函数 或
普通函数,

这种方式需要2个参数,

重载为 类的友元函数 和 普通函数的区别是
类的友元函数可以直接访问类的私有成员,而普通函数不可以。

2、应用举例(对象 ? 对象)


下例中有3个complex类 ComplexA、ComplexB 和
ComplexC,3个类都重载了加减乘除 运算符。

其中ComplexA使用类的非静态成员函数方式重载,ComplexB使用类的友元函数方式重载,ComplexC使用普通函数方式重载。

需要注意的是复数的加减乘除运算的算法是有问题的,只是一个说明重载方法的例子,

另外重载函数的参数最好使用const关键字限定,至于返回值是否用const限定,需要取决于你的设计,比如允许C3
= ++(C1+C2)这种情况,就不能用cosnt限定。

至于不同类型的对象间的操作,通常是没有意义的。


#include <iostream>
using namespace std;

class ComplexA
{
public:
//默认构造函数(Default constructor)
ComplexA(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
ComplexA(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
ComplexA(const ComplexA& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~ComplexA(){cout<<"Destructor"<<endl;}

//Operator Overload : +
ComplexA operator+(ComplexA& ref)
{
return ComplexA(real + ref.real, image + ref.image);
}

//Operator Overload : -
ComplexA operator-(ComplexA& ref)
{
return ComplexA(real - ref.real, image - ref.image);
}

//Operator Overload : *
ComplexA operator*(ComplexA& ref)
{
return ComplexA(real * ref.real, image * ref.image);
}

//Operator Overload : /
ComplexA operator/(ComplexA& ref)
{
return ComplexA(real / ref.real, image / ref.image);
}

//display
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //复数的实部
double image; //复数的虚部
};

class ComplexB
{
public:
//默认构造函数(Default constructor)
ComplexB(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
ComplexB(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
ComplexB(const ComplexB& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~ComplexB(){cout<<"Destructor"<<endl;}

//Operator Overload : +
friend ComplexB operator+(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real + ref2.real, ref1.image + ref2.image);
}

//Operator Overload : -
friend ComplexB operator-(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real - ref2.real, ref1.image - ref2.image);
}

//Operator Overload : *
friend ComplexB operator*(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real * ref2.real, ref1.image * ref2.image);
}

//Operator Overload : /
friend ComplexB operator/(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real / ref2.real, ref1.image / ref2.image);
}

//display
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //复数的实部
double image; //复数的虚部
};

class ComplexC
{
public:
//默认构造函数(Default constructor)
ComplexC(){cout<<"Default Constructor"<<endl;}
//带参数的构造函数(The constructor with parameters)
ComplexC(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
//拷贝构造函数(Copy constructor)
ComplexC(const ComplexC& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
//析构函数(destructor)
~ComplexC(){cout<<"Destructor"<<endl;}

//Get Data
double GetReal(void){return real;}
double GetImage(void){return image;}

  //display
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //复数的实部
double image; //复数的虚部
};

//Operator Overload : +
ComplexC operator+(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() + ref2.GetReal(), ref1.GetImage() + ref2.GetImage());
}

//Operator Overload : -
ComplexC operator-(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() - ref2.GetReal(), ref1.GetImage() - ref2.GetImage());
}

//Operator Overload : *
ComplexC operator*(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() * ref2.GetReal(), ref1.GetImage() * ref2.GetImage());
}

//Operator Overload : /
ComplexC operator/(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() / ref2.GetReal(), ref1.GetImage() / ref2.GetImage());
}

int main(void)
{
ComplexA C1(2,4), C2(1, 2), C3;
C3 = C1 + C2; C3.display();
C3 = C1 - C2; C3.display();
C3 = C1 * C2; C3.display();
C3 = C1 / C2; C3.display();
cout <<"--------------------------------------"<<endl;
ComplexB C4(2,4), C5(1, 2), C6;
C6 = C4 + C5; C6.display();
C6 = C4 - C5; C6.display();
C6 = C4 * C5; C6.display();
C6 = C4 / C5; C6.display();
cout <<"--------------------------------------"<<endl;
ComplexC C7(2,4), C8(1, 2), C9;
C9 = C7 + C8; C9.display();
C9 = C7 - C8; C9.display();
C9 = C7 * C8; C9.display();
C9 = C7 / C8; C9.display();
return 0;
}

3、应用举例(对象 ? 基本数据类型 or 基本数据类型 ?
对象)


上面的例子中是对象 和 对象之间的运算符重载,如果需要一个是对象
+ char/int/float/double,或者反过来 char/int/float/double
+ 对象,这时上面的程序的重载方式就不适用了。

需要定义新的重载,如下列程序所示。


#include <iostream>
using namespace std;

class ComplexD
{
public:
ComplexD(double re = 0, double im = 0):real(re),image(im){}

ComplexD operator+(ComplexD& ref){return ComplexD(real+ref.real, image+ref.image);};
ComplexD operator+(int a){cout<<"IN\t int \t\t";return ComplexD(real+a, image);};
ComplexD operator+(double d){cout<<"IN\t double \t";return ComplexD(real+d, image);};
ComplexD operator+(float f){cout<<"IN\t float \t\t";return ComplexD(real+f, image);};

void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
double GetReal(void){return real;}
double GetImage(void){return image;}
private:
double real;
double image;
};

ComplexD operator+(int a, ComplexD& ref){cout<<"OUT\t int \t\t";return ComplexD(ref.GetReal()+a, ref.GetImage());};
ComplexD operator+(double d, ComplexD& ref){cout<<"OUT\t double \t";return ComplexD(ref.GetReal()+d, ref.GetImage());};
ComplexD operator+(float f, ComplexD& ref){cout<<"OUT\t float \t\t";return ComplexD(ref.GetReal()+f, ref.GetImage());};

int main(void)
{
ComplexD D1(2,4), D2;
D2 = D1 + 2; D2.display();
D2 = D1 + 2.1f; D2.display();
D2 = D1 + 2.1; D2.display();

D2 = 2 +D1; D2.display();
D2 = 2.1f + D1; D2.display();
D2 = 2.1 +D1; D2.display();

return 0;
}

C++运算符重载——重载二元运算符

时间: 2024-07-30 12:12:39

C++运算符重载——重载二元运算符的相关文章

二元运算符重载

------------------siwuxie095 二元运算符重载 所谓 二元运算符,即 这个符号与两个操作数进行运算 (1)加号 + 的重载 加号 + 的重载方式有两种:一种是友元函数重载,一种是成员函数重载 1)先来看成员函数重载,如下: 定义一个坐标类:Coordinate 在类中声明成员函数 operator+(),它的参数是 const Coordinate &coor 在实现时: 首先需要定义一个临时对象 temp,传入对象 coor 的 m_iX 要和 当前对象的 m_iX

自增自减运算符的重载(强制类型转换运算符重载)

前置运算符重载为一元运算符,后置运算符重载为二元运算符. Operator int() { return n; } int作为一个强制类型转换运算符被重载, Demo s; (int)s;       //等效于s.int(): 强制类型转换运算符重载时, 不能写返回值类型 实际上其返回值类型----强制类型转换运算符代表的类型 只能作为成员函数,不能作为友元函数或普通函数 转换构造函数和类型转换运算符有一个共同的功能:当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量

JavaScript一元运算符、二元运算符和三元运算符

在JavaScript中,运算符可以根据其实际操作数的个数进行分类. JavaScript中的大多数运算符是一个二元运算符(binary operator),将两个表达式合并称为一个稍复杂的表达式.譬如a*b中的乘法运算符*,就是一个二元运算符.表达式-x中的-运算符就是一个一元运算符,是将操作数x求负值.最后,JavaScript支持一个三元运算符(ternary operator),条件判断运算符?:,它将三个表达式合并成一个表达式. 条件语句?(条件为真)执行语句A:(条件为假)执行语句B

C++之运算符重载(二元)

一.加号+ 1.成员函数重载 2.友元函数重载 二.输出符号<< 三.索引符号 [ ] 四.补充说明 1.<二元运算符重载>课程评论: (一)为什么<<运算符的重载必须定义为友元 如果在类中定义非友元成员函数,默认第一个参数默认会传入this*指针,这时就无法实现cout在前<<对象在后的格式 因为二元运算符中的调用格式是 参数一 运算符 参数二 这也就是为什么 加号运算符可以使用非友元成员函数,因为参数一是一个this*指针,参数二是其它对象 假设定义为非

C++ 运算符的重载(转载自http://blog.csdn.net/insistgogo/article/details/6626952)

(转载自http://blog.csdn.net/insistgogo/article/details/6626952) 什么是运算符的重载? 运算符与类结合,产生新的含义. 为什么要引入运算符重载? 作用:为了实现类的多态性(多态是指一个函数名有多种含义) 怎么实现运算符的重载? 方式:类的成员函数 或 友元函数(类外的普通函数) 规则:不能重载的运算符有 .  和 .* 和 ?: 和 ::  和 sizeof 友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使

C++——运算符的重载---以成员函数方式重载---以友元函数方式重载

一.运算符的重载 1.运算符的重载 允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载.运算符仅仅是语法上的方便,它是另一种函数调用的方式,只有在设计涉及的代码更容易写,尤其是更容易读的时候才有必要重载. 2.实现运算符重载的方式 类的成员函数 友元函数(即类外的普通函数) 3.运算符重载的原则: 不能重载的运算符有5个:  .  .*  ?: ::  sizeof 运算符重载不允许发明新的运算符 不能改变运算符操作对象的

重载运算与类型转换——基本概念,输入和输出运算符,算术和关系运算符,赋值运算符,下标运算符,递增和递减运算符,成员访问运算符

一.基本概念 重载的运算符时具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.和其他函数一样,重载的运算符也包含返回类型.参数列表以及函数体. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多.一元运算符有一个参数,二元运算符有两个.对于二元运算符来说,左侧运算对象传递给第一个参数,而右侧运算对象传递给第二个参数.除了重载的函数调用运算符operator()之外,其他重载运算符不能含有默认实参. 当一个重载的运算符时成员函数时,this绑定到左侧运算

C++中不可重载5个运算符

C++中不可重载的5个运算符 C++中的大部分运算符都是可以重载的,只有以下5个运算符不可以重载,他们是: 1  .(点运算符)通常用于去对象的成员,但是->(箭头运算符),是可以重载的 2  ::(域运算符)即类名+域运算符,取成员,不可以重载 3  .*(点星运算符,)不可以重载,成员指针运算符".*,即成员是指针类型 4  ?:(条件运算符)不可以重载 5  sizeof不可以重载

C++ 运算符的重载

#include <iostream> #include <stdio.h> using namespace std; class Complex //复数类 { public: double real;//实数 double imag;//虚数 Complex(double real=0,double imag=0) { this->real=real; this->imag=imag; } }; Complex operator+(Complex com1,Comp