0.目录

1.操作符重载

2.完善的复数类

3.小结

1.操作符重载

下面的复数解决方案是否可行?

示例1——原有的解决方案:

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } friend Complex Add(const Complex& p1, const Complex& p2);
}; Complex Add(const Complex& p1, const Complex& p2)
{
Complex ret; ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = Add(c1, c2); // c1 + c2 printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
c3.a = 4, c3.b = 6

操作符重载:

  • C++中的重载能够扩展操作符的功能
  • 操作符的重载以函数的方式进行
  • 本质——用特殊形式的函数扩展操作符的功能

通过operator关键字可以定义特殊的函数

operator的本质是通过函数重载操作符

语法:

示例2——使用操作符重载函数代替原有函数:

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } friend Complex operator + (const Complex& p1, const Complex& p2);
}; Complex operator + (const Complex& p1, const Complex& p2)
{
Complex ret; ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = operator + (c1, c2); // c1 + c2 printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
c3.a = 4, c3.b = 6

可以将操作符重载函数定义为类的成员函数:

  • 比全局操作符重载函数少一个参数(左操作符)
  • 不需要依赖友元就可以完成操作符重载
  • 编译器优先在成员函数中寻找操作符重载函数

示例3——不使用友元,而是使用类的成员函数(编译器优先在成员函数中寻找操作符重载函数):

#include <stdio.h>

class Complex
{
int a;
int b;
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
} int getA() { return a; } int getB() { return b; } Complex operator + (const Complex& p)
{
Complex ret;
printf("Complex operator + (const Complex& p)\n");
ret.a = this->a + p.a;
ret.b = this->b + p.b; return ret;
} friend Complex operator + (const Complex& p1, const Complex& p2);
}; Complex operator + (const Complex& p1, const Complex& p2)
{
Complex ret;
printf("Complex operator + (const Complex& p1, const Complex& p2)\n");
ret.a = p1.a + p2.a;
ret.b = p1.b + p2.b; return ret;
} int main()
{
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3 = c1 + c2; // c1.operator + (c2) printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Complex operator + (const Complex& p)
c3.a = 4, c3.b = 6

2.完善的复数类

复数类应该具有的操作:

利用操作符重载:

  • 统一复数与实数的运算方式
  • 统一复数与实数的比较方式

先实现Complex.h头文件:

// Complex.h
#ifndef _COMPLEX_H_
#define _COMPLEX_H_ class Complex
{
double a;
double b;
public:
Complex(double a = 0, double b = 0);
double getA();
double getB();
double getModulus(); Complex operator + (const Complex& c);
Complex operator - (const Complex& c);
Complex operator * (const Complex& c);
Complex operator / (const Complex& c); bool operator == (const Complex& c);
bool operator != (const Complex& c); Complex& operator = (const Complex& c);
}; #endif

再实现Complex.cpp具体操作:

// Complex.cpp
#include "Complex.h"
#include "math.h" Complex::Complex(double a, double b)
{
this->a = a;
this->b = b;
} double Complex::getA()
{
return a;
} double Complex::getB()
{
return b;
} double Complex::getModulus()
{
return sqrt(a * a + b * b);
} Complex Complex::operator + (const Complex& c)
{
double na = a + c.a;
double nb = b + c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator - (const Complex& c)
{
double na = a - c.a;
double nb = b - c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator * (const Complex& c)
{
double na = a * c.a - b * c.b;
double nb = a * c.b + b * c.a;
Complex ret(na, nb); return ret;
} Complex Complex::operator / (const Complex& c)
{
double cm = c.a * c.a + c.b * c.b;
double na = (a * c.a + b * c.b) / cm;
double nb = (b * c.a - a * c.b) / cm;
Complex ret(na, nb); return ret;
} bool Complex::operator == (const Complex& c)
{
return (a == c.a) && (b == c.b);
} bool Complex::operator != (const Complex& c)
{
return !(*this == c);
} Complex& Complex::operator = (const Complex& c)
{
if( this != &c )
{
a = c.a;
b = c.b;
} return *this;
}

最后实现main函数:

// test.cpp
#include <stdio.h>
#include "Complex.h" int main()
{
Complex c1(1, 2);
Complex c2(3, 6);
Complex c3 = c2 - c1;
Complex c4 = c1 * c3;
Complex c5 = c2 / c1; printf("c3.a = %f, c3.b = %f\n", c3.getA(), c3.getB());
printf("c4.a = %f, c4.b = %f\n", c4.getA(), c4.getB());
printf("c5.a = %f, c5.b = %f\n", c5.getA(), c5.getB()); Complex c6(2, 4); printf("c3 == c6 : %d\n", c3 == c6);
printf("c3 != c4 : %d\n", c3 != c4); (c3 = c2) = c1; printf("c1.a = %f, c1.b = %f\n", c1.getA(), c1.getB());
printf("c2.a = %f, c2.b = %f\n", c2.getA(), c2.getB());
printf("c3.a = %f, c3.b = %f\n", c3.getA(), c3.getB()); return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp Complex.cpp
[root@bogon Desktop]# ./a.out
c3.a = 2.000000, c3.b = 4.000000
c4.a = -6.000000, c4.b = 8.000000
c5.a = 3.000000, c5.b = 0.000000
c3 == c6 : 1
c3 != c4 : 1
c1.a = 1.000000, c1.b = 2.000000
c2.a = 3.000000, c2.b = 6.000000
c3.a = 1.000000, c3.b = 2.000000

注意事项:

  • C++规定赋值操作符(=)只能重载为成员函数
  • 操作符重载不能改变原操作符的优先级
  • 操作符重载不能改变操作符的个数
  • 操作符重载不应改变操作符的原有语义

3.小结

  • 操作符重载是C++的强大特性之一
  • 操作符重载的本质是通过函数扩展操作符的功能
  • operator关键字是实现操作符重载的关键
  • 操作符重载遵循相同的函数重载规则
  • 全局函数和成员函数都可以实现对操作符的重载
  • 复数的概念可以通过自定义类实现
  • 复数中的运算操作可以通过操作符重载实现
  • 赋值操作符只能通过成员函数实现
  • 操作符重载的本质为函数定义

C++解析(17):操作符重载的更多相关文章

  1. Kotlin操作符重载:把标准操作加入到任何类中(KAD 17)

    作者:Antonio Leiva 时间:Mar 21, 2017 原文链接:https://antonioleiva.com/operator-overload-kotlin/ 就像其他每种语言一样, ...

  2. 析构函数-复制构造函数-赋值操作符重载-默认构造函数<代码解析>

    通过下面primer中的一道习题,可以更深刻的了解,析构函数,复制构造函数,赋值操作符重载,默认构造函数的使用. 但是我的结果与primer习题解答里面的并不相同,可能是编译器不同的原因导致. // ...

  3. lua 14 metatable (类似操作符重载)

    转自:http://www.runoob.com/lua/lua-metatables.html 感性认识: “Lua中Metatable这个概念, 国内将他翻译为元表. 元表为重定义Lua中任意一个 ...

  4. 【转】Python3 操作符重载方法

    Python3 操作符重载方法 本文由 Luzhuo 编写,转发请保留该信息. 原文: http://blog.csdn.net/Rozol/article/details/70769628 以下代码 ...

  5. 5.1 C++基本操作符重载

    参考:http://www.weixueyuan.net/view/6379.html 总结: 操作符重载指的是将C++提供的操作符进行重新定义,使之满足我们所需要的一些功能. 长度运算符“sizeo ...

  6. 侯捷STL学习(四)--OOP-GP/操作符重载-泛化特化

    C++标准库第二讲 体系结构与内核分析 第1-7节为第一讲 读源代码前的准备 第八节:源代码分布 C++基本语法 模板的使用 数据结构和算法 本课程主要使用:Gnu C 2.9.1与Gun C 4.9 ...

  7. C++ 操作符重载 (operator)

    重载不能改变操作符的优先级 如果一个内建操作符是一元的,那么所有对它的重载仍是一元的.如果是二元的重载后也是二元的 下面看一个有代表性的例子:: 头文件Complex.h: #includeusing ...

  8. c++ 操作符重载和友元

    操作符重载(operator overloading)是C++中的一种多态,C++允许用户自定义函数名称相同但参数列表不同的函数,这被称为函数重载或函数多态.操作符重载函数的格式一般为: operat ...

  9. paip.操作符重载的缺失 Java 的一个大缺点

    paip.操作符重载的缺失 Java 的一个大缺点 #----操作符重载的作用 1.提升用户体验 操作符重载..可以让代码更加自然.... 2.轻松实现代码代码移植 例如   java代码会直接移植到 ...

随机推荐

  1. 【Loj10222】佳佳的Fibonacci

    题面 题解 可以发现\(T(n)\)无法用递推式表示. 于是我们做如下变形: \[ T(n) = \sum _ {i = 1} ^ n i \times f_i \\ S(n) = \sum _ {i ...

  2. PHP:Iterator(迭代器)接口和生成器

    迭代器 可在内部迭代自己的外部迭代器或类的接口.详情:http://php.net/manual/zh/class.iterator.php 接口摘要 Iterator extends Travers ...

  3. Tree Traversals Again(根据前序,中序,确定后序顺序)

    题目的大意是:进行一系列的操作push,pop.来确定后序遍历的顺序 An inorder binary tree traversal can be implemented in a non-recu ...

  4. 使用MyBatis遇到的一些需要记录下的问题

    (1)MyBaits结果集返回Map,Map集合乱序. xml 中的SQL 输出: 改成: 输出: 目测跟字母顺序有关:ABCDEFGHIJKLMNOPQRSTUVWXYZ (2)需要对字段动态排序 ...

  5. sqlserver-查阻塞

    模拟阻塞: 打开两个窗口:     窗口一: BEGIN TRANSACTION--开始事务 --等待1分钟 WAITFOR DELAY '00:1'; 窗口二: 查询阻塞:(当前被阻塞的进程id,不 ...

  6. hbase 预分区

    转载 http://www.cnblogs.com/bdifn/p/3801737.html

  7. Thunder团队——bug修正

    团队:欢迎来怼 发现的问题: 1.首先用户通过爱阅APP内部的网址跳转到各大电子书网站时,需要额外启动手机自身浏览器:就以豆瓣网为例,阅读豆瓣网上的一些书籍,是跳转到手机自带浏览器的,APP内部提供的 ...

  8. Linux 下web开发环境搭建-jdk环境搭建

    Centos 7 附:windows 下jdk环境变量 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools ...

  9. C++寒假计划

    课程 西北工业大学的c++程序设计 理由 这个课程里的内容都比较详细,能比较全面的讲解C++,我们是从C过渡到C++的,所以我之前看了阚道洪的面向对象程序设计的课程,他讲解了两者的差别,还有C++对C ...

  10. 周总结<1>

    由于都不清楚周总结的格式,所以就没有写了.不过,上次听了老师的课,觉得应该要好好写写了,至少今后可以明白自己有做过什么事情,至少不会觉得自己在各个方面没有收获.不过,可能没有按照格式来写.希望老师体谅 ...