魔方网站,广告公司的名字怎么起好,瑞安做网站,如何知道网站用什么程序做的以下内容源于C语言中文网的学习与整理#xff0c;非原创#xff0c;如有侵权请告知删除。
一、运算符重载的含义
所谓重载#xff0c;就是赋予新的含义。函数重载#xff08;Function Overloading#xff09;可以让一个函数名有多种功能#xff0c;在不同情况下进行不同…以下内容源于C语言中文网的学习与整理非原创如有侵权请告知删除。
一、运算符重载的含义
所谓重载就是赋予新的含义。函数重载Function Overloading可以让一个函数名有多种功能在不同情况下进行不同的操作。运算符重载Operator Overloading也是一个道理同一个运算符可以有不同的功能。
二、运算符重载的格式
运算符重载的格式为
返回值类型 operator 运算符名称 (形参表列)
{ //TODO:
}
1operator是关键字专门用来定义一个函数运算符重载函数。可以将 “operator 运算符名称”这一部分看做函数名。比如对于上面的代码函数名就是operator。
2运算符重载函数除了函数名有特定的格式外其它地方和普通函数并没有区别。
三、简单的例子说明
例子1运算符重载函数作为成员函数
#includeiostreamusing namespace std;class complex {
public:complex();complex(double real, double imag);
public:complex operator (const complex A) const;void display() const;
private:double m_real;double m_imag;};complex::complex() :m_real(0.0), m_imag(0.0) {}
complex::complex(double real, double imag) : m_real(real), m_imag(imag) {}complex complex::operator (const complex A) const {complex B;B.m_real this-m_real A.m_real;B.m_imag this-m_imag A.m_imag;return B;
}void complex::display() const {cout m_real m_imag i endl;
}int main() {complex c1(4.3, 5.6);complex c2(2.3, 3.7);complex c3;c3 c1 c2;c3.display();return 0;
}
上面的例子中我们在 complex 类中重载了运算符该重载只对 complex 对象有效。
当执行“c3 c1 c2;”语句时编译器检测到号左边号具有左结合性所以先检测左边是一个 complex 对象就会调用成员函数operator()也就是转换为下面的形式
c1.operator(c2)
即 c1 这个对象调用了函数operator而 c2 是函数的实参。
例子2运算符重载函数作为全局函数
#include iostream
using namespace std;class complex{
public:complex();complex(double real, double imag);
public:void display() const;//声明为友元函数friend complex operator(const complex A, const complex B);
private:double m_real;double m_imag;
};complex operator(const complex A, const complex B);complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }
void complex::display() const{coutm_real m_imagiendl;
}//在全局范围内重载
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;
}int main(){complex c1(4.3, 5.8);complex c2(2.4, 3.7);complex c3;c3 c1 c2;c3.display();return 0;
}
因为该运算符重载函数不是 complex 类的成员函数但是却用到了 complex 类的 private 成员变量所以必须在 complex 类中将该函数声明为友元函数。
当执行“ c3 c1 c2;” 语句时编译器检测到号两边都是 complex 对象就会转换为类似下面的函数调用c3 operator(c1, c2); 总结虽然运算符重载所实现的功能完全可以用函数替代但运算符重载使得程序的书写更加人性化易于阅读。运算符被重载后原有的功能仍然保留没有丧失或改变而通过运算符重载扩大了C已有运算符的功能使之能用于对象。 四、运算符重载时要遵循的规则
1、并不是所有的运算符都可以重载。
2、重载不能改变运算符的优先级和结合性。
3、重载不会改变运算符的用法原来有几个操作数、操作数在左边还是在右边这些都不会改变。例如 号总是出现在两个操作数之间重载后也必须如此。
4、运算符重载函数不能有默认的参数否则就改变了运算符操作数的个数这显然是错误的。
5、运算符重载函数既可以作为类的成员函数也可以作为全局函数。
1将运算符重载函数作为类的成员函数时二元运算符的参数只有一个一元运算符不需要参数。之所以少一个参数是因为这个参数是隐含的比如上面的例子1。
2将运算符重载函数作为全局函数时二元操作符就需要两个参数一元操作符需要一个参数而且其中必须有一个参数是对象记忆运算符重载是在c引入对象时才有的概念所以它的一个参数是对象好让编译器区分这是程序员自定义的运算符防止程序员修改用于内置类型的运算符的性质。
例如下面这样是不对的
int operator (int a,int b){return (a-b);
}
号原来是对两个数相加现在企图通过重载使它的作用改为两个数相减 如果允许这样重载的话那么表达式43的结果是 7 还是 1 呢显然这是绝对禁止的。
如果有两个参数这两个参数可以都是对象也可以一个是对象一个是C 内置类型的数据例如
complex operator(int a, complex c){return complex(ac.real, c.imag);
}
它的作用是使一个整数和一个复数相加。
3另外将运算符重载函数作为全局函数时一般都需要在类中将该函数声明为友元函数。原因很简单该函数大部分情况下都需要使用类的 private 成员。
6、箭头运算符-、下标运算符[ ]、函数调用运算符( )、赋值运算符只能以成员函数的形式重载。
五、重载数学运算符示例
四则运算符、-、*、/、、-、*、/和关系运算符、、、、、!都是数学运算符它们在实际开发中非常常见被重载的几率也很高并且有着相似的重载格式。本节以复数类 Complex 为例对它们进行重载重在演示运算符重载的语法以及规范。
复数能够进行完整的四则运算但不能进行完整的关系运算我们只能判断两个复数是否相等但不能比较它们的大小所以不能对 、、、 进行重载。下面是具体的代码
#include iostream
#include cmath
using namespace std;//复数类
class Complex{
public: //构造函数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);friend Complex operator-(const Complex c1, const Complex c2);friend Complex operator*(const Complex c1, const Complex c2);friend Complex operator/(const Complex c1, const Complex c2);friend bool operator(const Complex c1, const Complex c2);friend bool operator!(const Complex c1, const Complex c2);//以成员函数的形式重载Complex operator(const Complex c);Complex operator-(const Complex c);Complex operator*(const Complex c);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 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;
}
//重载*运算符 (abi) * (cdi) (ac-bd) (bcad)i
Complex operator*(const Complex c1, const Complex c2){Complex c;c.m_real c1.m_real * c2.m_real - c1.m_imag * c2.m_imag;c.m_imag c1.m_imag * c2.m_real c1.m_real * c2.m_imag;return c;
}
//重载/运算符 (abi) / (cdi) [(acbd) / (c²d²)] [(bc-ad) / (c²d²)]i
Complex operator/(const Complex c1, const Complex c2){Complex c;c.m_real (c1.m_real*c2.m_real c1.m_imag*c2.m_imag) / (pow(c2.m_real, 2) pow(c2.m_imag, 2));c.m_imag (c1.m_imag*c2.m_real - c1.m_real*c2.m_imag) / (pow(c2.m_real, 2) pow(c2.m_imag, 2));return c;
}
//重载运算符
bool operator(const Complex c1, const Complex c2){if( c1.m_real c2.m_real c1.m_imag c2.m_imag ){return true;}else{return false;}
}
//重载!运算符
bool operator!(const Complex c1, const Complex c2){if( c1.m_real ! c2.m_real || c1.m_imag ! c2.m_imag ){return true;}else{return false;}
}//重载运算符
Complex Complex::operator(const Complex c){this-m_real c.m_real;this-m_imag c.m_imag;return *this;
}
//重载-运算符
Complex Complex::operator-(const Complex c){this-m_real - c.m_real;this-m_imag - c.m_imag;return *this;
}
//重载*运算符
Complex Complex::operator*(const Complex c){this-m_real this-m_real * c.m_real - this-m_imag * c.m_imag;this-m_imag this-m_imag * c.m_real this-m_real * c.m_imag;return *this;
}
//重载/运算符
Complex Complex::operator/(const Complex c){this-m_real (this-m_real*c.m_real this-m_imag*c.m_imag) / (pow(c.m_real, 2) pow(c.m_imag, 2));this-m_imag (this-m_imag*c.m_real - this-m_real*c.m_imag) / (pow(c.m_real, 2) pow(c.m_imag, 2));return *this;
}int main(){Complex c1(25, 35);Complex c2(10, 20);Complex c3(1, 2);Complex c4(4, 9);Complex c5(34, 6);Complex c6(80, 90);Complex c7 c1 c2;Complex c8 c1 - c2;Complex c9 c1 * c2;Complex c10 c1 / c2;coutc7 c7.real() c7.imag()iendl;coutc8 c8.real() c8.imag()iendl;coutc9 c9.real() c9.imag()iendl;coutc10 c10.real() c10.imag()iendl;c3 c1;c4 - c2;c5 * c2;c6 / c2;coutc3 c3.real() c3.imag()iendl;coutc4 c4.real() c4.imag()iendl;coutc5 c5.real() c5.imag()iendl;coutc6 c6.real() c6.imag()iendl;if(c1 c2){coutc1 c2endl;}if(c1 ! c2){coutc1 ! c2endl;}return 0;
}
需要注意的是我们以全局函数的形式重载了 、-、*、/、、!以成员函数的形式重载了 、-、*、/而且应该坚持这样做不能一股脑都写作成员函数或者全局函数具体原因我们将在下节讲解。