• 非成员版本

    data1 + data2;

    operator+(data1, data2);

  • 成员版本

    data1 += data2;

    data1.operator+=(data2);

  • 不建议的重载

逻辑与、逻辑或、逗号的运算对象求值顺序规则无法保留。
&&和||的重载版本也没法保留内置运算符的短路求值属性,两个运算对象总是会被求值。
逗号和取址,已经在C++中定义了其用于类对象是的特殊含义,已经有了内置的含义,一般不应该重载。
  • 有些运算符必须作为成员,有些则作为普通函数更好

    1. 赋值= 下标[] 调用() 成员访问箭头->必须是成员
    2. 复合赋值一般应该是成员,但并非必须
    3. 改变对象状态的运算符或者与给定类型密切相关的运算符,如++,--,解引用通常是成员
    4. 具有对称性的,可能转换任意一端的运算符对象,如算术、相等性、关系和位运算,通常是非成员。
  • 输出运算符<<

ostream &operator<<(ostream &os, const Sales_data &item)
输出运算符不太考虑格式化操作,使用户有权控制输出细节
与iostream标准库兼容的输入输出运算符必须是非成员函数
  • 输入运算符>>
istream &operator>>(istream &is, Sales_data &item)
输入运算符必须处理可能失败的情况(数据类型错误,到底文件尾或遇到输入流其他错误)
  • 算术和关系
通常定义为非成员,通常不需要改变运算对象(常量引用),计算得到一个新值。
如定义了复合赋值,最有效的是使用复合赋值来定义算术运算。
Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) bool operator==(const Sales_data &lhs, cosnt Sales_data &rhs)
bool operator!=(const Sales_data &lhs, cosnt Sales_data &rhs)
  • 关系运算符
1 定义顺序关系,与关联容器对关键字的要求一致(唯一性、传递性、等价性)
2 如果同时含有==的话,则定义一种关系令其与==保持一致
当存在一种唯一可靠的<定义,且和==产生的结果一致时,才定义<
  • 赋值运算符
StrVec &StrVec::operator=(initializer_list<string> il)
Sales_data &Sales_data::operater+=(const Sales_data &rhs)
赋值运算符必须是成员函数,复合赋值也通常定义为成员函数。
一般算术运算调用复合赋值,可读写较好
  • 下标运算
通常返回引用,最好同时定义常量和非常量版本,必须成员函数
std::string &operator[](std::size_t n) {return elements[n];}
const std::string &operator[](std::size_t n) const {return elements[n];}
  • 递增递减
StrBlobPtr& StrBlobPtr::operator++()    前置版本
StrBlobPtr StrBlobPtr::operator++(int) 后置版本
后置可以调用前置来完成,前置版本需检查递增操作的有效性。一般设定为成员函数。
  • 成员访问
class StrBlob{
public:
std::string &operator*() const
{ auto p = check(curr, “dereference past end”;
return (*p)[curr];
}
std::string *operator->() const
{
return & this->operator*();
}
}
箭头必须成员,解引用也通常成员
箭头运算符永远不能丢掉成员访问的基本含义
point->mem
point必须是指向类对象的指针或者是重载了operator->的类对象
1是指针,等价于(*point).mem
2是对象,调用point.operator->()的结果来获取mem。如果返回的是指针则执行第1步;如果返回的结果本身重载了->,则重复调用。或者返回错误。
  • 调用运算符
函数对象,同时也能储存状态,比普通函数更灵活
同一个对象里可以重载好几个不同版本的调用函数,同时可以改变数据成员来定制不同操作。隐含的this参数呢???看调用的形式
  • lambda是未命名类的未命名对象
默认情况下,是一个const成员函数,不能改变它捕获的变量。显式声明为mutable则不是。
产生的类不含默认构造函数、赋值运算符及默认析构函数??
是否含有默认的拷贝/移动构造要视捕获的数据类型而定。
  • 标准库定义的函数对象
算术 关系 逻辑
plus equal_to logical_and
minus not_equal_to logical_or
multiplies greater logical_not
divides greater_equal
modulus less
negate less_equal
常用来替换算法中的默认运算符,这些函数对象对指针同样适用。
sort(a.beg,a.end, less<string*>() ); //正确
而用<,则将产生未定义的行为 关联容器使用less<key_type>对元素排序,可以定义一个指针作为关键字的set或map而无须直接声明less
  • 可调用对象
函数、函数指针、lambda表达式、bind创建的对象、重载了函数调用运算符的类。
fun &fun和funP打印的地址是一样的。funP可以被赋值,而fun不可以。有两种解释
1函数名与FunP函数指针都是函数指针。fun是一个函数指针常量,funP是一个函数数指针变量。
2函数名和数组名实际上都不是指针,但是,在使用时可以退化成指针,即编译器可以帮助我们实现自动的转换。 既然都是都有指针的效果,为什么要定义函数指针?
二义性问题,如有几个版本add函数,不知道哪个?
起到一定的封装效果,可以提供统一接口。C++虚函数表就是通过函数指针实现。 不同类型调用对象可能共享同一种调用形式
map<string, int(*)(int, int)> binops;能存函数指针,存不了函数对象和lambda function类 <functional>
可以接受同调用类型的可调用对象
function<int (int, int)> f1=add; map<string,function<int(int,int)>> binops = {
{“+”, add},
{“-”, std::minus<int>()} };
binops[“+”](10, 5); //调用add(10, 5) 类型转换可以面向任何可以作为返回类型的类型,不允许转换成数据或函数类型。,必须定位为成员函数,通常const。
编译器只能进行一个用户定义的类型转换,但是隐式地用户定义类型转换可以置于一个标准(内置)类型转换之前或之后。
explicit operator int() const {return val;}
static_cast<int>(si)+3;
一个例外,当用作条件时,编译器会将显式的类型转换自动应用于它。
if while do for 与或非 ?:
  • 避免二义性
两个类提供相同的类型转换
类定义了多个转换规则
当使用用户定义的类型转换时,如果包含标准类型转换,转换的级别决定了最佳匹配选择

C/C++基础----重载运算与类型转换的更多相关文章

  1. C++ Primer 5th 第14章 重载运算与类型转换

    当运算符作用域类类型的对象时,可以通过运算符重载来重新定义该运算符的含义.重载运算符的意义在于我们和用户能够更简洁的书写和更方便的使用代码. 基本概念 重载的运算符是具有特殊名字的函数:函数名由关键词 ...

  2. c++ 重载运算与类型转换

    1. 基础概念 重载的运算符是具有特殊名字的函数:(重载运算符函数,运算符函数.重载运算符) 依次包含返回类型,函数名(operator=),参数列表,函数体. 只有重载的函数调用运算符operato ...

  3. 【c++ Prime 学习笔记】第14章 重载运算与类型转换

    14.1 基本概念 重载的运算符是特殊的函数:名字由关键字operator后接要定义的算符共同组成,也有返回类型.参数列表.函数体. 重载运算符函数的参数量与该算符作用的运算对象数量一样多 除重载调用 ...

  4. C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符

    重载前须知 重载运算符是特殊的函数,它们的名字由operator和其后要重载的运算符号共同组成. 因为重载运算符时函数, 因此它包含返回值.参数列表和函数体. 对于重载运算符是成员函数时, 它的第一个 ...

  5. 高放的c++学习笔记之重载运算与类型转换

    ▲基本概念 (1)重载运算符是具有特殊名字的函数,它们的名字又operator和其后要定义的运算符号共同构成.. (2)对于一个运算符号来说它或者是类的成员,或者至少含有一个类类型的参数. (3)我们 ...

  6. 【转载】DSP基础--定点小数运算

    在FPGA实现算法过程中,大多数情况是用占用资源较少,延迟较低的定点数代替浮点数参与运算.那么浮点与定点数之间的区别以及转换方式是怎么的?下边这篇博文详细说明了这一问题.虽然是针对DSP芯片的,但思想 ...

  7. 「C语言」数据类型及混合运算与类型转换

    深入学习C语言时,有必要先了解一下数据类型的概念,以及它们之间的混合运算与类型转换. 本篇文章便是根据<C语言程序设计教程>和在线翻阅资料后整理而出.(练习题将逐步更新) 目录:     ...

  8. C++ Primer 笔记——重载运算

    1.对于二元运算符来说,左侧运算对象传递给第一个参数,而右侧运算对象传递给第二个参数.除了重载的函数调用运算符operator()之外,其他重载元素运算符不能含有默认实参. class test { ...

  9. [C++ Primer] : 第14章: 重载运算符与类型转换

    基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...

随机推荐

  1. Django中HtttpRequest请求

    1.什么是HttpRequest HttpRequest,就是对请求对象的封装,里面封装的是请求过程中的所有信息.在Django中HttpRequest被封装成request对象并封装到视图处理函数中 ...

  2. seo:网站被黑的预防及处理方法

    一.网站被黑的类型有哪些 1.网站挂木马  :通过网站后台 FTP等植入恶意代码 2.网站域名被恶意泛解析 3.跳转 4.百度快照劫持:黑客劫持快照在你不工作的时候进入你的网站的,一般是凌晨1点到5. ...

  3. xdoj-1324 (区间离散化-线段树求区间最值)

    思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i]  覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...

  4. 一个简易的drf的项目例子

    luffy_city 1.项目介绍 今日内容:(路飞项目) contentType组件: 路飞学成项目,有课程,学位课(不同的课程字段不一样),价格策略 问题, 如何设计表结构,来表示这种规则 为专题 ...

  5. Redis(二)持久化

    Redis持久化,分为RDB方式和AOF方式,它们可以单独使用,也可以混用.Redis默认的是使用RDB方式. 一.RDB方式 1.触发快照的方式 RDB方式是在指定时间间隔内某一时间点的数据集快照. ...

  6. draw graph

    http://www.icl.pku.edu.cn/member/yujs/bsdfiles/html/mpost.htmlUNIX下绘图面面观 http://www.tug.org/metapost ...

  7. SpringMVC(二)高级

    高级参数绑定 1.1. 绑定数组 1.1.1. 需求 在商品列表页面选中多个商品,然后删除. 1.1.2. 需求分析 功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按 ...

  8. setjmp与longjmp非局部跳转函数的使用

    [root@bogon code]# cat c.c #include<stdio.h> #include<setjmp.h> static jmp_buf env;//定义全 ...

  9. plsql快速入门

    汉化plsql方法: 本来想直接使用英文版的,但是太多专业名词看不懂,只好先汉化熟悉一下先. 安装好plsq后,百度下载plsql汉化包 执行汉化包里面的安装程序,安装目标路径选择plsql的安装路径 ...

  10. gaia 开源多语言的pipeline 平台

    gaia 是一个支持goalng.java.c++.python,nodejs (还在开发中)的pipeline 平台,我们可以方便的进行pipeline构建的 添加,同时也可以做为sdk 在我们的项 ...