C++类基础(十一)

news2024/11/15 11:05:49

运算符重载(二)
● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换

struct Str
{
    int val = 0;
    Str(int input)
        : val(input)
    {}
    auto operator+(Str x)
    {
        std::cout << "auto operator+(Str x)\n";
        return Str(val + x.val);
    }
};
int main()
{
    Str x = 3;
    Str z = x + 4; //通过类Str的构造函数将4转换为Str类型与x相加
    Str u = 4 + x; //Error: Invalid operands to binary expression ('int' and 'Str')
    return 0;
}

在这里插入图片描述

struct Str
{
    int val = 0;
    Str(int input)
        : val(input)
    {}
};
auto operator+(Str input1, Str input2)
{
    std::cout << "auto operator+(Str input1, Str input2)\n";
    return Str(input1.val + input2.val);
}
int main()
{
    Str x = 3;
    Str y = x + 3; OK
    return 0;
}
struct Str
{
    Str(int input)
        : val(input)
    {}
    friend auto operator+(Str, Str);
private:
    int val = 0;
};
auto operator+(Str input1, Str input2)
{
    std::cout << "auto operator+(Str input1, Str input2)\n";
    return Str(input1.val + input2.val);
}
int main()
{
    Str x = 3;
    Str y = x + 3;
    Str z = 3 + y;
    return 0;
}

● 移位运算符一定要定义为非成员函数,因为其首个操作数类型为流类型

struct Str
{
    Str(int input)
        : val(input)
    {}
    friend auto operator+(Str input1, Str input2)
    {
        return Str(input1.val + input2.val);
    }
    friend auto& operator<<(std::ostream& output, Str input) //返回引用,第一个参数类型是std::ostream
    {
        output << input.val;
        return output;
    }
private:
    int val = 0;
};
int main()
{
    Str x = 3;
    Str y = x + 3;
    std::cout << x << ' ' << y <<std::endl;
    return 0;
}

在这里插入图片描述

● 赋值运算符也可以接收一般参数

struct Str
{
    Str()
        : val(0)
    {}
    Str(int input)
        : val(input)
    {}
    Str& operator=(const Str& input) //重载赋值运算符1。重载运算符只接受一个参数,因为缺省参数是*this。
    {
        val = input.val;
        return *this;
    }
    Str& operator=(const std::string& input) //重载赋值运算符2
    {
        val = static_cast<int>(input.size());
        return *this;
    }
//private:
    int val;
};
int main()
{
    Str x = 3;
    //Str y = "12345"; //调用构造函数而非重载赋值运算符
    Str y;
    y = "12345"; //调用重载赋值运算符
    std::cout << y.val << std::endl;
    return 0;
}

在这里插入图片描述

● operator [] 通常返回引用

struct Str
{
    Str()
        : val(0)
    {}
    Str(int input)
        : val(input)
    {}
    Str& operator=(const Str& input) //重载赋值运算符1,
    {
        val = input.val;
        return *this;
    }
    Str& operator=(const std::string& input) //重载赋值运算符2
    {
        val = static_cast<int>(input.size());
        return *this;
    }
    //int operator[](int id) //返回“值”,只读,不可执行写操作
    int& operator[](int id) //#1返回引用,可读可写,但是*this可被修改
    {
        return val;
    }
    int operator[](int id) const //#2const修饰构成重载返回“值”,可读不可写,即*this不可被修改
    {
        return val;
    }
//private:
    int val;
};
int main()
{
    Str x = 3;
    x = "12345";
    std::cout << x[0] << '\n'; //读
    x[0] = 100; //写
    std::cout << x[0] << '\n';
    const Str cx = 3;
    //std::cout << cx[0] << std::endl; //见#1,Error: No viable overloaded operator[] for type 'const Str'
    std::cout << cx[0] << std::endl; //OK,见#2
    return 0;
}

在这里插入图片描述

● 自增、自减运算符的前缀、后缀重载方法

struct Str
{
    Str()
        : val(0)
    {}
    Str(int input)
        : val(input)
    {}
    //Str operator++() //返回“值”,Error: cannot increment value of type 'void'
    Str& operator++() //前缀自增
    {
        ++val;
        return *this;
    }
    Str operator++(int) //后缀自增,返回“值”
    {
        Str tmp(*this); //调用拷贝构造,构造临时对象,编译器不一定能优化,导致性能上的损失
        ++val;
        return tmp;
    }
//private:
    int val;
};
int main()
{
    Str s;
    ++(++s); //调用前缀自增
    std::cout << s.val <<std::endl;
    std::cout << (s++).val << std::endl; //调用后缀自增
    std::cout << s.val <<std::endl;
    return 0;
}

在这里插入图片描述

● 使用解引用运算符( * )与成员访问运算符( -> )模拟指针行为
– 注意“ .” 运算符不能重载

通过类对象而不是指向类对象的指针调用其成员的,所以不能重载

struct Str
{
    Str(int* p)
        : ptr(p)
    {}
    //operator*() //Error: C++ requires a type specifier for all declarations
    int& operator*() //返回引用,支持读写操作
    {
        return *ptr;
    }
    int operator*() const //返回“值”,只读
    {
        return *ptr;
    }
private:
    int* ptr;
};
int main()
{
    int x = 100;
    Str ptr(&x);
    std::cout << *ptr << std::endl; //读
    *ptr = 101; //写
    std::cout << *ptr << std::endl;
    return 0;
}

在这里插入图片描述

– “→” 会递归调用 操作 “→”

struct Str
{
    Str(int* p)
        : ptr(p)
    {}
    Str* operator ->() //重载运算符本质上是个函数
    {
        return this;
    }
    int val = 5;
private:
    int* ptr;
};
int main()
{
    int x = 100;
    Str ptr(&x);
    std::cout << ptr->val << std::endl; //#1
    std::cout << (ptr.operator->()->val) << std::endl; //#2 #1与#2等价
    return 0;
}

在这里插入图片描述

struct Str2
{
    Str2* operator->()
    {
        return this;
    }
    int blabla = 20;
};

struct Str
{
    Str(int* p)
        : ptr(p)
    {}
    Str2 operator ->() //类Str中重载->运算符返回Str2类对象
    {
        return Str2{};
    }
    int val = 5;
private:
    int* ptr;
};
int main()
{
    int x = 100;
    Str ptr(&x);
    std::cout << ptr->blabla << std::endl; //#1
    std::cout << (ptr.operator->().operator->()->blabla) << std::endl; //#2 #1与#2等价
    return 0;
}

在这里插入图片描述

int operator->() //Error: member type 'int' is not a pointer
{
    return blabla;
}

int* operator->() //Error: member reference base type 'int' is not a structure or a union
{
    return &blabla;
}

● 使用函数调用运算符构造可调用对象

struct Str
{
    Str(int p)
        : val(p)
    {}
    int operator()()
    {
        return val;
    }
    int operator()(int x, int y, int z) //参数列表不同,重载
    {
        return val + x + y +z;
    }
private:
    int val;
};
int main()
{ 
    Str obj(100);
    std::cout << obj() << std::endl;
    std::cout << obj(1, 2, 3) << std::endl;
    return 0;
}

在这里插入图片描述

struct Str
{
    Str(int p)
        : val(p)
    {}
    int& operator()()
    {
        return this->val;
    }
    bool operator()(int input) //参数依据实际情况修改,更加灵活,是Lambda表达式的基础
    {
        //return val < input;
        return val++ < input;
    }
private:
    int val;
};
int main()
{ 
    Str obj(100);
    std::cout << obj() << std::endl;
    std::cout << obj(1) << std::endl;
    std::cout << obj() << std::endl;
    std::cout << obj(199) << std::endl;
    std::cout << obj() << std::endl;
    return 0;
}

在这里插入图片描述

参考
深蓝学院:C++基础与深度解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/340293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git 常用命令之 git log

大家好&#xff0c;我是 17。 git log dev 查看 dev 分支的 log git log -p 每次提交所引入的差异 git log --stat 每次提交的简略统计信息 git log --name-status 比 --stat 更简洁&#xff0c;更常用。git log -2 最近两次提交 git log --since2.weeks 最近两周内的提交 git…

Linux通配符、转义符讲解

目录 通配符 通过通配符定义匹配条件 转义符 将所有的逻辑操作符都转换成字符 通配符 通过通配符定义匹配条件 * 任意字符都可以通配&#xff08;也可以匹配空值&#xff09; &#xff1f; 匹配单个字符 [a-z] 匹配单个的小写英文字母 [A-Z] 匹配单个的大写英文…

jQuery 基础知识(五)

前面已经介绍HTML、CSS和javaScript&#xff0c;这三个前端语言&#xff0c;俗称前端三剑客。下面来学习一个javaScript简化并封装好的库——jQuery库。01 - AJAX AJAX 是一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术。 AJAX的介绍 ajax 是 Asynchr…

freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间

freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间 freesurfer如何将组模板投影到个体空间? freesurfer如何将组模板投影到个体空间——如投影 Schaefer2018 到个体空间freesurfer的整理流程freesurfer的安装freesurfer对结构像分割流程及批处理代码fr…

git 常用命令之 git checkout

大家好&#xff0c;我是 17。 git checkout 是 git 中最重要最常用的命令之一&#xff0c;本文为大家详细解说一下。 恢复工作区 checkout 的用途之一是恢复工作区。 git checkout . checkout . 表示恢复工作区的所有更改,未跟踪的文件不会有变化。 恢复工作区的所有文件风…

硬件工程师入门基础知识(一)基础元器件认识(二)

硬件工程师入门基础知识 &#xff08;一&#xff09;基础元器件认识&#xff08;二&#xff09; tips&#xff1a;学习资料和数据来自《硬件工程师炼成之路》、百度百科、网上资料。 1.二极管 2.三极管 3.MOS管 4.IGBT 5.晶振 1.二极管 肖特基二极管和硅二极管的比较&#…

架构方法论

0.缘起最近在和同事以及相关领域的人沟通时&#xff0c;大家都在强调架构、架构图&#xff0c;于是兴起了一片关于架构的方法论介绍。本文对内容的组织按照顶层设计思路&#xff0c;先对架构本身进行剖析&#xff1a;什么是架构&#xff1f;为什么架构很重要&#xff1f;这些是…

大家心心念念的RocketMQ5.x入门手册来喽

1、前言 为了更好的拥抱云原生&#xff0c;RocketMQ5.x架构进行了大的重构&#xff0c;提出了存储与计算分离的设计架构&#xff0c;架构设计图如下所示&#xff1a; RocketMQ5.x提供了一套非常建议的消息发送、消费API&#xff0c;并统一放在Apache顶级开源项目rocketmq-clie…

T07 奥运排序问题

描述 按要求&#xff0c;给国家进行排名。 输入描述&#xff1a; 有多组数据。 第一行给出国家数N&#xff0c;要求排名的国家数M&#xff0c;国家号从0到N-1。 第二行开始的N行给定国家或地区的奥运金牌数&#xff0c;奖牌数&#xff0c;人口数&#xff08;百万&#xff09…

【c/c++】c语言的自增操作在不同编译器的差别

示例代码 代码如下&#xff1a; #include <stdio.h>#define product(x) ((x)*(x))int main(void) {int i 3, j, k;j product(i); // (i) * (i)k product(i); // (i) * (i)printf("%d %d\n", j, k); }执行结果 在Ubuntu18.04下通过GCC编译和执行的结果…

【在执行make geth报错解决方法】

在执行make geth报错解决方法问题详细描述&#xff1a;详细解决方法对根据报错提示信息对相关文件夹权限进行修改2、再次执行make geth 检查是否还报错问题详细描述&#xff1a; Ubuntu 版本&#xff1a;18.04问题&#xff1a;在编译运行以太坊源码执行make geth命令时报错&am…

*from . import _imaging as core : ImportError: DLL load failed: 找不到指定的模块

错误提示如上。为了解决这个问题&#xff0c;首先参考了解决 from . import _imag…模块。. 首先尝试了彻底卸载pillow&#xff1a;conda uninstall pillow &#xff1b; pip uninstall pillow 然后重装 pip install pillow&#xff0c;发现问题仍然没有解决。 并且尝试了windo…

湿敏电阻的原理,结构,分类与应用总结

🏡《总目录》 0,概述 湿敏电阻是指电阻值随着环境的湿度变化而变化的电阻,本文对其工作原理,结构,分类和应用场景进行总结。 1,工作原理 湿敏电阻是利用湿敏材料制成的,湿敏材料吸收空气中水分时,自身的阻值发生变化。 2,结构 如下图所示,市民电阻包括4个部分构成,…

SpringBoot+Vue实现智能物流管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…

【手写 Vuex 源码】第七篇 - Vuex 的模块安装

一&#xff0c;前言 上一篇&#xff0c;主要介绍了 Vuex 模块收集的实现&#xff0c;主要涉及以下几个点&#xff1a; Vuex 模块的概念&#xff1b;Vuex 模块和命名空间的使用&#xff1b;Vuex 模块收集的实现-构建“模块树”&#xff1b; 本篇&#xff0c;继续介绍 Vuex 模…

gradle命令

环境搭建 $ mkdir /opt/gradle $ unzip -d /opt/gradle gradle-7.6-bin.zip $ ls /opt/gradle/gradle-7.6 LICENSE NOTICE bin getting-started.html init.d lib media配置环境变量 $ export PATH=$PATH:/opt/gradle/gradle-7.6/bin检查配置是否ok gradle -v Android …

Elasticsearch7.8.0版本进阶——分布式集群(应对故障)

目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装&#xff08;win10环境&#xff09;1.2、Elasticsearch集群的安装&#xff08;linux环境&#xff09;二、应对故障&#xff08;win10环境集群演示&#xff09;2.1、启动集群&#xff08;三个节点&#xff09;2.2、…

Lecture4 反向传播(Back Propagation)

目录 1 问题背景 1.1计算图&#xff08;Computational Graph&#xff09; 1.2 激活函数&#xff08;Activation Function&#xff09;引入 1.3 问题引入 2 反向传播&#xff08;Back Propagation&#xff09; 2.1 为什么要使用反向传播 2.2 前馈运算(Forward Propagation…

Allegro如何更改临时高亮的颜色设置操作指导

Allegro如何更改临时高亮的颜色设置操作指导 在用Allegro做PCB设计的时候,当移动或者高亮某个对象之前,会被临时高亮一个颜色,方便查看,类似下图 运行高亮命令的时候,器件被临时高亮成了白色 软件默认的是白色,如何更改成其它颜色? 具体操作如下 点击Display选择Color…

西瓜书读书笔记—绪论

文章目录机器学习典型的机器学习过程基本术语归纳偏好机器学习 机器学习&#xff1a;致力于研究如果通过计算的手段&#xff0c;利用经验来改善系统自身的性能 在计算机系统中&#xff0c;“经验” 通常以 “数据” 形式存在&#xff0c;因此&#xff0c;机器学习所研究的主要内…