15.C++-操作符重载、并实现复数类
首先回忆下以前学的函数重载
函数重载
- 函数重载的本质为相互独立的不同函数
- 通过函数名和函数参数来确定函数调用
- 无法直接通过函数名得到重载函数的入口地址
- 函数重载必然发生在同一个作用域中
类中的函数重载
- 静态成员函数能与普通成员函数建立重载关系
- 全局函数和成员函数不能构成重载关系
操作符重载(operator)
什么是操作符重载?
大家都知道,在C里,有'+,-,*,/'这些操作符,且它们的功能就是实现普通变量运算。
由于C++是面向对象的,遇到的变量大多都是对象,所以优化了C里的操作符,使它们拥有了重载能力.能通过一定方式,使对象能进行'+,-,*,/'等运算.
操作符的重载是以函数的方式进行.
操作符重载定义
操作符重载,通过operator关键字在函数前定义:
[返回类型] operator [需要重载的操作符](函数参数) { //...... }
操作符重载有几种方式 : 全局操作符重载函数、全局操作符重载函数
编译器首先会判断运算的若是对象,就会先从类里寻找成员操作符重载函数,若没找到,就会再去全局里寻找全局操作符重载函数.
注意事项:
- 操作符重载不能改变原操作符的优先级
- 操作符重载不能改变操作数的个数
- 操作符重载的参数一般设为const class_name &类型(若只设为const class_name,会产生临时对象)
- 在C++中,有些操作符必须需要有对象支持,所以只能为成员函数.这种被称为一元操作符
比如赋值(=)、下标([])、下标([])、调用(())和成员访问箭头(->):
Test t3=t2; //相当于调用了: Test t3.operator =(t2); 里面会通过this指针来代替左侧数t3
- 有些操作符既可以当做成员操作符重载函数,也可以当做全局操作符重载函数,由于函数参数可以多个,便称为二元操作符
比如加法(+),与(&&),或(||),逗号(,)等:
以加法(+)为例,当设为全局操作符重载函数时,执行
Test t3=t1+t2; //相当于调用了: Test t3 = operator +(t1,t2);
以加法(+)为例,当设为成员操作符重载函数时,执行
Test t3=t1+t2; //相当于调用了: Test t3 =t1.operator +(t2); //里面会通过this指针来代替左侧数t1
多个重载的操作符重载函数
由于操作符重载函数带参数,所以可以存在多个相同的操作符重载函数
例如:
class Test
{ double x; double y; public: Test operator +(const Test& t); //实现Test t3=t1+t2 Test operator +(int i); //实现Test t3=t1+1 Test operator +(double d); //实现Test t3=t1+1.25 //... ... };
初步试验
1.接下来,来个全局操作符重载函数例子:
#include "stdio.h" class Test{ int x;
int y; public:
Test(int x=0,int y=0)
{
this->x=x;
this->y=y;
}
int getx()
{
return x;
}
int gety()
{
return y;
} friend Test operator + (const Test& t1,const Test& t2);
//声明友元函数,可以使用私有成员变量 }; Test operator + (const Test& t1,const Test& t2) //重载
{
Test ret;
ret.x=t1.x+t2.x;
ret.y=t1.y+t2.y;
return ret;
} int main()
{
Test t1(1,3);
Test t2(2,4);
Test t3= t1 + t2; // 其实就是调用: Test t3 = operator +(t1,t2); printf("t3.x:%d t3.y:%d\n",t3.getx(),t3.gety()); Test t4 =operator +(t1,t3); // t4 =t1 +t3 printf("t4.x:%d t4.y:%d\n",t4.getx(),t4.gety()); return 0;
}
打印结果:
t3.x:3 t3.y:7
t4.x:4 t4.y:10
2.换成成员操作符重载函数例子:
#include "stdio.h" class Test{ int x;
int y; public:
Test(int x=0,int y=0)
{
this->x =x;
this->y =y;
} int getx()
{
return x;
} int gety()
{
return y;
} Test operator + (const Test& t2)
{
Test ret; ret.x = this->x + t2.x;
ret.y = this->y + t2.y;
return ret;
}
}; int main()
{
Test t1(1,3);
Test t2(2,4);
Test t3= t1 + t2; // 其实就是调用: Test t3 =t1.operator +(t2); printf("t3.x:%d t3.y:%d\n",t3.getx(),t3.gety()); Test t4 =t1.operator +(t3); // t4 =t1 +t3 printf("t4.x:%d t4.y:%d\n",t4.getx(),t4.gety()); return 0;
}
打印结果:
t3.x:3 t3.y:7
t4.x:4 t4.y:10
加深理解
由于C++里,没有复数的慨念,而在刚刚又学习了操作符重载,所以接下来便通过操作符重载来实现复数类
复数类应该具有
两个成员
实部a 、虚部b
运算操作符
+ - : 结果 = 两个实部进行加减,两个虚部进行加减
* : 结果 = (a1+b1)(a2+b2)= (a1*a2 - b1*b2 )+( a2*b1 + a1*b2);
/ : 结果 =(a1+b1)/(a2+b2)= (a1*a2+b1*b2)/(a2* a2+b2* b2) +(b1*a2-a1*b2)/(a2* a2+b2* b2)
比较操作符:== ,!=
赋值操作符: =
求模成员函数 : 等于a^2+b^2的算术平方根
所以复数类的操作符重载共有以下几个:
1.写头文件Complex.h:
#ifndef __COMPLEX_H
#define __COMPLEX_H class Complex{ private:
double a;
double b; public:
Complex(int a=0,int b=0);
Complex operator + (const Complex& t);
Complex operator - (const Complex& t);
Complex operator * (const Complex& t);
Complex operator / (const Complex& t);
bool operator == (const Complex& t);
bool operator != (const Complex& t);
Complex& operator = (const Complex& t); double getModulus(); double getA();
double getB();
}; #endif
2.写源文件Complex.cpp
#include "Complex.h"
#include "math.h" Complex::Complex(int a,int b)
{
this->a = a;
this->b = b;
} Complex Complex::operator + (const Complex& t)
{
Complex ret; ret.a = a + t.a;
ret.b = b + t.b;
return ret;
} Complex Complex::operator - (const Complex& t)
{
Complex ret; ret.a = a - t.a;
ret.b = b - t.b;
return ret;
} Complex Complex::operator * (const Complex& t)
{
Complex ret;
ret.a = (a* t.a - b* t.b );
ret.b = (t.a *b + a* t.b );
return ret;
} Complex Complex::operator / (const Complex& t)
{
Complex ret;
ret.a = (a* t.a + b* t.b)/(t.a * t.a + t.b * t.b);
ret.b = (b* t.a - a* t.b)/(t.a * t.a + t.b * t.b);
return ret;
} bool Complex::operator == (const Complex& t)
{
if((a== t.a)&&(b== t.b))
return true; else
return false;
} bool Complex::operator != (const Complex& t)
{
if((a!= t.a)||(b!= t.b))
return true; else
return false;
} Complex& Complex::operator = (const Complex& t)
{
if(this != &t)
{
a = t.a;
b = t.b;
}
return *this;
} double Complex::getModulus()
{
return sqrt( a*a + b*b);
} double Complex::getA()
{
return a;
} double Complex::getB()
{
return b;
}
3.写测试文件test.cpp
#include "stdio.h"
#include "Complex.h" int main()
{
Complex t1(1,3);
Complex t2(2,6); Complex t3=t1+t2; printf("t3.a=%f t3.b=%f\n",t3.getA(),t3.getB()); printf("t3 Modulus:%f\n",t3.getModulus()); Complex t4=t3; printf("t4==t3: %d\n",t4==t3);
printf("t4!=t3: %d\n",t4!=t3);
printf("t3==t1: %d\n",t3==t1); return 0;
}
4.编译运行
t3.a=3.000000 t3.b=9.000000
t3 Modulus:9.486833
t4==t3: 1 //为真
t4!=t3: 0 //为假
t3==t1: 0 //为假
15.C++-操作符重载、并实现复数类的更多相关文章
- 15.C++-操作符重载
首先回忆下以前学的函数重载 函数重载 函数重载的本质为相互独立的不同函数 通过函数名和函数参数来确定函数调用 无法直接通过函数名得到重载函数的入口地址 函数重载必然发生在同一个作用域中 类中的函数重载 ...
- C++学习笔记15:操作符重载的函数原型列表(推荐)
//普通四则运算 friend A operator +(const A & lhs, const A & rhs); friend A operator -(const A & ...
- [GeekBand] C++学习笔记(1)——以复数类为例
本篇笔记以复数类(不含指针的类)为例进行面向对象的学习 ========================================================= 复数类的声明: class ...
- 5.1 C++基本操作符重载
参考:http://www.weixueyuan.net/view/6379.html 总结: 操作符重载指的是将C++提供的操作符进行重新定义,使之满足我们所需要的一些功能. 长度运算符“sizeo ...
- C++解析(17):操作符重载
0.目录 1.操作符重载 2.完善的复数类 3.小结 1.操作符重载 下面的复数解决方案是否可行? 示例1--原有的解决方案: #include <stdio.h> class Compl ...
- C++中操作符重载的概念
1,下面的复数解决方案是否可行? 1,代码示例: class Comples { public: int a; int b; }; int main() { Complex c1 = {, }; Co ...
- C++ operator overload -- 操作符重载
C++ operator overload -- 操作符重载 2011-12-13 14:18:29 分类: C/C++ 操作符重载有两种方式,一是以成员函数方式重载,另一种是全局函数. 先看例子 # ...
- C++ 操作符重载 (operator)
重载不能改变操作符的优先级 如果一个内建操作符是一元的,那么所有对它的重载仍是一元的.如果是二元的重载后也是二元的 下面看一个有代表性的例子:: 头文件Complex.h: #includeusing ...
- C++ 数组操作符重载、函数对象分析、赋值操作符
string类型访问单个字符 #include <iostream> #include <string> #include <sstream> using name ...
随机推荐
- 尝试asp.net mvc 基于controller action 方式权限控制方案可行性(转载)
微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...
- Python-实现图表绘制总结
Numpy是Python开源的数值计算扩展,可用来存储和处理大型矩阵,比Python自身数据结构要高效: matplotlib是一个Python的图像框架,使用其绘制出来的图形效果和MATLAB下绘制 ...
- 简单线性回归问题的优化(SGD)R语言
本编博客继续分享简单的机器学习的R语言实现. 今天是关于简单的线性回归方程问题的优化问题 常用方法,我们会考虑随机梯度递降,好处是,我们不需要遍历数据集中的所有元素,这样可以大幅度的减少运算量. 具体 ...
- 输入URL地址到最终页面渲染完成,发生了什么事
1. 域名DNS解析 - 浏览器DNS缓存 - 系统DNS缓存 - 路由器DNS缓存 - 网络运营商DNS缓存 - 递归搜索...... 2. TCP连接: TCP三次握手 - 第一次握手,由浏览器发 ...
- ubuntu下wps无法使用搜狗输入法输入中文
sudo vim /usr/bin/et sudo vim /usr/bin/wps sudo vim /usr/bin/wpp 以上三个文件,都加入如下内容后重新打开文档即可 export XMOD ...
- Docker仓库(四)
一.什么是仓库 仓库就是集中存放镜像的地方,分为公共仓库和私有仓库,一个容易混淆的概念是注册服务器,实际上注册服务器是存放仓库的具体服务器,一个注册服务器可以有多个仓库,而每个仓库下面有多个镜像 二. ...
- canvars 画花
index.html <!DOCTYPE html><html><head> <title>旋转的花</title> <meta ch ...
- sql server 2008 R2
SQL SERVER 2008 R2序列号: 数据中心版:PTTFM-X467G-P7RH2-3Q6CG-4DMYB 开 发者 版:MC46H-JQR3C-2JRHY-XYRKY-QWPVM 企 ...
- wordpress添加文章阅读数量
将下面代码添加到functions.php //取得文章的阅读次数 function post_views($before = '点击 ', $after = ' 次', $echo = 1) { g ...
- Mysql 锁机制和事务
InnoDB 锁机制 InnoDB存储引擎支持行级锁 其大类可以细分为共享锁和排它锁两类 共享锁(S):允许拥有共享锁的事务读取该行数据.当一个事务拥有一行的共享锁时,另外的事务可以在同一行数据也获得 ...