C++运算符重载总结(真的很详细了w(゚Д゚)w)

概述

运算符重载可以使得一些特殊类型参与运算,我是这样理解的。


使用友元形式的运算符重载

//一般形式
class x{
friend 返回类型 operator 运算符(形参表);
};
返回类型 operator 运算符(形参表)
{}

双目运算符

所以加减乘除就可以这样来进行声明了

返回类型 operator +(-、*、/) (形参表);

单目运算符

- & ! ++(前),++(后)等。下面以++(后)来进行一个示例:

class code{
int x, y;
};
code operator++(code& op, int)//第二个参数仅仅表示这个++是后缀加
{
code tmp(op);
x++;
y++;
return tmp;//返回增加之前的状态,这样也对后加加有了进一步理解了。
}

总结:

  1. 运算符重载可以返回任何类型,甚至是void类型,但是通常都是返回和操作数相同的类型。

  2. 下面运算符只能使用成员函数运算符重载,不能使用友元函数来重载。

    运算符名称
    = 等号
    [] 下标运算符
    () 函数调用运算符
    -> 指针成员运算符
  3. 对于同一个运算符,可以写多个函数来进行重载。


使用成员运算符进行重载

//一般形式
class x{
返回类型 operator 运算符(参数表);
}
返回类型 x::operator 运算符(参数表)
{
具体实现
}

双目运算符重载

这里需要注意的是:参数表中的个数会少一个,因为左操作数是隐含在this中的。

但是类内的静态函数没有this指针。

例如:

class code{
int x, y;
public:
code(int a, int b):x(a), y(b){}
code operator+(code p){
return code(x+p.x, y+p.y);
}
};
code A(1, 2), B(3, 4);
code C=A+B;//这时C.x=4, C.y=6;

单目运算符重载

形式和上面差不多,这里不再赘述。


运算符重载需要注意的几个问题

  1. c++语言只能对已经有的c++运算符进行重载,不允许用户自己定义新的运算符。

  2. 绝大多数运算符都能重载,但是有例外,下面五个不能进行重载

    名称
    . 成员访问运算符
    .* 成员指针访问运算符
    :: 作用域运算符
    sizeof 长度运算符
    ?: 条件运算符
  3. 重载的功能应当和原有的功能类似

  4. 重载不能改变运算符的操作对象

  5. 重载不能改变运算符原有的优先级

  6. 重载不能改变运算符原有的结合特性

  7. 重载参数应该至少有一个是类对象,不能都是c++预定义的类型(要不然就没有意义了)

  8. 双目运算符一般两种重载形式都可以,但是有的时候只能用友元形式来进行重载。例如:

    AB::operator+(int x){
    return AB(a+x, b+x);
    }
    ob1=ob2+100; //这里这样调用是可以的,编译器理解为ob1=ob2.operator(100);
    //但是下面的情况就会出现问题
    ob1=100+ob2; //等价于ob1=100.operator(ob2);但是100不是一个对象

    如果我们定义下面两个友元函数就会很好的解决这个问题

    friend AB operator+(AB ob, int x);
    friend AB operator+(int x, AB ob);
    //这样ob1=100+ob2; ob1=ob2+100;都没有问题
    //这里我们也可以整合,使用类型转换函数,将int类型转换为对象类型,对象类型转换为int类型,不过真没啥意思

几个常见的运算符重载

等号“ = ”运算符重载,只能使用成员函数进行重载

这里我们重载=主要是进行深拷贝操作(当然这里也可以自己写一个拷贝构造函数来进行)。

在重载等号运算符重载时要注意自己等于自己的情况

mystring& mystring::operator=(mystring &s)
{
if(this==&s)return *this;//防止出现s=s的赋值;
if(p!=NULL)
delete []p;
p=new char[strlen(s.p)+1];
strcpy(p, s.p);
return *this;
}

下标运算符重载[]

只能使用成员函数进行重载,要注意这是个双目运算符x[y],x是左操作符,y是右操作符**

返回类型 类名::operator[] (参数表){
函数体
}
//有时返回类型可以使用引用类型,只要不是返回的变量不是在函数内声明的临时变量就可以
class AB{
int num[10];
int len;
int& operator[](int);
}
int& AB::operator[](int b)
{
if(b<0 || b>=10)
return -1;
else return num[b]; //这里num[b]不是一个临时变量,而是存在于对象中。
}

函数调用运算符重载()

只能使用成员函数进行重载

注意这里()看被作双目运算符的,x(y), x是左操作数,y是右操作数

//给出坐标,返回二维矩阵的某个元素的值.
class matrix{
int *m;//用一维的数组来进行模拟
int row, col; //行数,列数
}
int& matrix::operator()(int r, int c){
return *(m+r*col+c);
}
m(3, 5)//这里解释为m.operator()(3, 5);

()运算符是唯一一个可带多个右操作数的运算符函数


输出运算符和输入运算符的重载

<<运算符的重载

定义原型:需要注意成员函数形式和友元函数形式的区别,他们调用方式不相同

//成员函数类型,注意如果使用下面的类型,那么调用的方式是:对象名<<cout;
ostream& operator<<(ostream& out){
out<<x<<" "<<y<<endl;
return out;
}
ob<<cout;//相当于ob.operator<<(cout);
//因为上面这种形式有点反直觉,所以很少用,所以大部分都是采用友元形式 //友元函数类型
friend ostream& operator<<(ostream& out, 自定义类名& 对象名){
//out可以改为别的名
out<<对象.x<<对象.y<<endl;
return out;
}
cout<<ob; //使用这种形式来进行输出

对于<<的参数详解,《C++ Primer中文版:第五版》\(494\)页是这样解释的:

输出运算符的第一个形参是一个非常量的ostream对象的引用。之所以ostream是非常量是因为向流写入内容会改变其状态;而该形参是因为我们无法复制一个ostream对象。

第二个形参一般来说是一个常量的引用,该常量是我们想要打印的类类型。第二个形参是引用的原因是我们希望避免赋值实参;而之所以该形参可以是常量是因为(通常情况下)打印对象不会改变对象的内容。

为了与其他输出运算符保持一致,operator<<一般要返回它的ostream形参。

>>输入运算符重载

这里的基本规则和上面重载输出运算符差不多,需要多注意的是,输入过程中要考虑到输入可能失败的情况。

C++运算符重载总结(真的很详细了w(゚Д゚)w)的更多相关文章

  1. C/C++ typedef用法详解(真的很详细)

    第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, ...

  2. 字符串为空的比较 ==与equals() 区别(キ`゚Д゚´)!!基础很重要 !!!

    情况描述:我提交的代码,让老大审批了一次,讲真的,对于我来说受益匪浅,其中有一个印象很深的内容:一个字符串是否为空的判断,我以前敲代码一直都是这样写的,可是从来都没有意识到这个东西. 代码: if(s ...

  3. C++ 重载运算符 继承 多态 (超详细)

    (一)重载运算符: (1)声明与定义格式 一般是类内声明,类外定义,虽然可以在类内定义,但 写前面堆一堆不好看!!! 类内声明: class Demo { 返回值类型 operator 运算符(形参表 ...

  4. C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

    首先,介绍三种重载方式: //作为成员函数重载(常见) class Person{ Private: string name; int age; public: Person(const char* ...

  5. C/C++对Lu系统内置动态对象进行运算符重载

    欢迎访问Lu程序设计 C/C++对Lu系统内置动态对象进行运算符重载 1 说明 要演示本文的例子,你必须下载Lu32脚本系统.本文的例子需要lu32.dll.lu32.lib.C格式的头文件lu32. ...

  6. C++运算符重载讲解与经典实例

    最近在学C++,找到一篇详细讲解运算符重载的文章,贴在这里分享和收藏. C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.例如: class  ...

  7. C++之运算符重载(前置++和后置++)

    今天在阅读<google c++ 编程风格>的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理 ...

  8. C++运算符重载的妙用

    运算符重载(Operator overloading)是C++重要特性之中的一个,本文通过列举标准库中的运算符重载实例,展示运算符重载在C++里的妙用.详细包含重载operator<<,o ...

  9. 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态

        C++运算符重载函数基础及其值返回状态 运算符重载是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观. 对于普通对象来说我们很自然的会频繁使用算数运 ...

随机推荐

  1. vue中使用elementUi (分页器的使用)

    1.安装 npm i element-ui -S 2.在main.js中引入 import ElementUI from 'element-ui' import 'element-ui/lib/the ...

  2. jquery文章链接

    好文链接 1.jQuery是js的一个库,封装了js中常用的逻辑: 2.调用jQuery: (1).本地调用,在script标签的src属性里写上jQuery文件的地址. (2).使用CDN调用jQu ...

  3. 【译】XMLHttpRequest和Fetch, 谁最适合AJAX?

    原文地址:https://www.sitepoint.com/xmlhttprequest-vs-the-fetch-api-whats-best-for-ajax-in-2019/ 目录 从AJAX ...

  4. Vuex的基本原理与使用

    我们需要知道 vue 是单向数据流的方式驱动的 什么是vuex? 为什么要使用vuex ? - 多个视图依赖于同一状态. - 来自不同视图的行为需要变更同一状态. vuex 类似Redux 的状态管理 ...

  5. 从零开始学习Gradle之三---多项目构建

       随着信息化的快速发展,IT项目变得越来越复杂,通常都是由多个子系统共同协作完成.对于这种多系统.多项目的情况,很多构建工具都已经提供了不错的支持,像maven.ant.Gradle除了借鉴了an ...

  6. Maximum upload size exceede上传文件大小超出解决

    在这里记录三种方法, 努力提高自己的姿势水平 application.yml配置 spring: servlet: multipart: enabled: true max-file-size: 10 ...

  7. CodeForces 137A

    Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description Polyca ...

  8. VS Code 调试 Golang 出现 Failed to continue: Check the debug console for details

    VS Code断点调试Golang时候,弹出提示:Failed to continue: Check the debug console for details 点击Open launch.json, ...

  9. 九、封装登录POST请求、登录后POST请求以及GET请求

    一.封装登录后POST请求以及GET请求 /** * 全局运行时环境参数管理器 */ public static Map<String, String> BASE_GLOBAL_MAP; ...

  10. router 配置按需加载对应的组件,配置active

    const routes = [ { path: '/', component: App, children: [ {path: '/index/:type', name: 'index', comp ...