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

1 基本概念

1.1 基本点

  1. 隐式的this指针
  2. 运算符函数至少有一个类类型参数
  3. 重载运算符的优先级应与内置运算符一致
  4. ::, .*, ., ? : 不可重载

1.2 重载的运算符函数的调用方式

1) 非成员函数的调用   operator+为对象data1, data2的非成员函数

data1 + data2;        ==> operator+(data1 , data2);

2) 成员函数的调用    operator+为对象data1的成员函数

data1 + data2        ==> data1.operator+(data2);

1.3 不应该重载的运算符

重载的运算符本质上就是函数调用.

1) 运算符的求值顺序无法保留        如: && , || , & , | 等

2) 无法保留运算符的短路求值属性

1.4 使用与内置类型一致的含义

1.5 成员与非成员选择

  • =, [], (), -> 必须为成员
  • 复合赋值一般为成员
  • 改变对象状态或与给定对象密切相关的,通常为成员. 如, ++, -- , * 解引用
  • 具有对称性的运算符, 如算术, 相等性, 关系和位, 通常为非成员.

1) 含对象的混合类型表达式,则运算符必须定义成非成员.

2) 当定义为成员函数时, 左侧运算对象必须是运算符所属类的一个对象.

2 输入与输出

输入输出运算符必须是非成员函数,一般为友元.

2.1 <<

ostream & operator<<(ostream &os, const Object &item ){
	os<< item.data1<< " "<< item.data2;
	return os;
}
  1. 第一个参数为非常量ostream引用
  2. 第二个参数常量引用
  3. 返回ostream型参
  4. 进来减少格式化操作,如换行.

2.2 >>

istream &  operator>>(isteam &is, Object &item){
	double p;
	is >> item.data1>>item.data2>>p;
	if(is){
		item.data2 = item.data2 * p;
	}else{
		item = Object();//输入失败:对象被赋予默认状态
	}
	return is;
}
  1. 第一个参数非常量istream
  2. 第二个参数非常量对象引用
  3. 错误检测
  4. 返回给定流对象引用

3 算术与关系

  1. 常量引用
  2. 返回一个新对象
  3. 一般定义对应的复合运算,用它来实现该运算.
  4. ==和!=一般成对出现

4 赋值

拷贝赋值, 移动赋值,列表赋值,复合赋值

赋值运算符必须为类成员,复合赋值通常也为成员.这两类都返回左侧对象的引用.

5 下标

  1. 必须为成员
  2. 提供非常量版和常量版

6 递增与递减

  1. 前置和后置成对出现
  2. 返回对象引用
  3. 后置版本先记录对象的状态,再操作,返回记录的对象

7 成员访问

  1. 常量this
  2. * 和 ->成对出现
  3. *返回& , ->返回指针
  4. *先检测是否在作用范围
  5. 箭头运算符必须返回指针或定义了箭头运算符的某个对象
<span style="font-size:14px;">class StrPtr {
public:
	std::string& operator*() const {
		auto p = check(curr, "dereference past end");
		return (*p)[curr];

	}

	std::string* operator->() const{
		return &this->operator*();
	}
//其他内容
}</span>

8 函数调用

  1. 定义了调用运算符的对象,称为函数对象
  2. 可以含有状态数据

8.1 lambda是函数对象

8.2 标准库函数对象

8.3 可调用对象和function

  • c++中的可调用对象: 函数, 函数指针, lambda表达式, bind创建的对象,重载了函数调用运算符的类.
  • 可调用对象也有自己的类型,不同类型可能具有相同的调用形式
  • 标准库function类型--->相同调用形式类型
  • 重载函数的名字不能直接存入function类型的对象.解决方法1, 通过函数指针; 2, lambda

9 类型转换运算符

  1. 必须为成员函数
  2. 无返回值,无参数
  3. 通常是const this
  4. 转换后的类型与函数返回类型要求相同,即不能是数组或函数类型,但可以是它们的指针
  5. 是隐式转换,一般不提供

加explicit变成显示转换,注意在以下条件显示转换将自动变成隐式转换

  1. if, while, do的条件部分
  2. for的条件部分
  3. 逻辑非, 或, 与(!, || , &&)
  4. 条件运算符的条件表达式

例子:IO类istream, ostream

9.1 避免有二义性的类型转换

  1. 实参匹配和相同的类型转换
  2. 转换目标为内置类型的多重类型转换
  3. 重载函数与转换构造函数
  4. 重载函数与用户定义的类型转换

9.2 函数匹配与重载运算符

如果我们对同一个类即提供转换目标是算术类型的类型转换,也提供了重载的运算符,则将会遇到重载运算符与内置运算符的二义性问题.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-14 00:33:48

c++ 重载运算与类型转换的相关文章

C++11(13):重载运算与类型转换

除了重载的函数调用运算符operator()之外,其他重载运算符不能含有默认实参. 当以个重载的运算符是成员函数时,this绑定到左侧运算对象.成员运算符函数的(显式)参数比运算对象的数量少一个. 当运算符作用于内置类型的运算对象时,我们无法改变运算的含义. ::              .*                     .          ?:   这四个运算符不能被重载. 我们只能重载已有的运算符,不能发明新的.优先级和结合律不变. data1 + data2; operat

第十五章、重载运算与类型转换

一.基本概念 1.重载运算符是具有特殊名字的函数:由关键字operator和其他要定义的运算符号共同组成 2.重载运算符的参数数量与该运算符作用的运算对象一样多 当一个重载的运算符是成员函数时,this会绑定到左侧运算对象,成员运算符函数的显示参数数量比运算对象的数量少一个 3.对于一个运算符函数,它要么是类的成员,或者至少含有一个类类型的参数 当作用符作用于内置类型的运算对象时,无法改变该运算符的含义 例: //非成员运算符函数的等价调用 data1 + data2: //普通的表达式 ope

c++ primer(第五版)学习笔记及习题答案代码版(第十四章)重载运算与类型转换

笔记较为零散,都是自己不熟悉的知识点. 习题答案至于一个.h 和.cc 中,需要演示某一题直接修改 #define NUM****, 如运行14.30题为#define NUM1430: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful f

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

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

C++之重载运算与类型转换

重载的运算符是具有特殊名字的函数:他们的名字是由关键字operator和其后定义的运算符号共同组成.重载运算符也包含返回类型.参数列表和函数体. 重载运算符的参数数量与该运算符作用的运算对象数量一样多.一元运算符有一个参数.二元运算符有两个参数.对于二元运算符来说,左侧对象传递给第一个参数,而右侧对象传递给第二个参数.除了operator(),其他重载运算符不能含有默认实参. 如果一个运算符函数是成员函数,则它的第一个(左侧)运算对象绑定到隐式的this指针上,因此成员运算符函数的参数数量比运算

C++重载运算与类型转换 整理笔记

C++重载运算简介

本文基于<C++ Primer(第5版)>中14章和<More Effective C++>条款7,整理而成. 其实写这篇博客之前,内心还是很忐忑的,因为,博主的水平很有限,视野比较窄,要是在理解书的过程中有了偏差,给读到这篇博客的人以错误的认识,那罪过就大了.再次声明本文仅是简介,若是有错误的地方欢迎留言指出. 个人认为运算符最重要的是:使用与内置类型一致的含义. 一.基本概念 当运算作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义. 重载的运算符是具有特别名字

python数学运算的类型转换

类型转换 Rational类实现了有理数运算,但是,如果要把结果转为 int 或 float 怎么办? 考察整数和浮点数的转换: >>> int(12.34) 12 >>> float(12) 12.0 如果要把 Rational 转为 int,应该使用: r = Rational(12, 5) n = int(r) 要让int()函数正常工作,只需要实现特殊方法__int__(): class Rational(object): def __init__(self,

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

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