15. C++泛型与符号重载


【泛型编程】

若多组类型不同的数据需要使用相同的代码处理,在C语言中需要编写多组代码分别处理,这样做显然太过繁琐,C++增加了虚拟类型,使用虚拟类型可以实现一组代码处理多种类型的数据。

虚拟类型是暂时不确定的数据类型,它在定义时不指定具体类型,而是在使用时指定类型,可以用于单个数据类型,也可以用于数组、结构体,使用虚拟类型编程也称为泛型编程,意为广泛类型。

使用虚拟类型的代码称为模板,但是全局数据不能使用虚拟类型,全局数据也无需定义为模板。

全局函数模板

函数模板的参数、返回值可以使用虚拟类型,参数与返回值的数量必须相同,只是类型不同。

#include <iostream>
template <typename T>   //使用template关键词定义虚拟类型,T为虚拟类型名称
T add(T t1, T t2)
{return t1+t2;
}
int main()
{printf("%d\n", add(1, 2));          //T指定为int类型printf("%f\n", add(0.1f, 0.2f));    //T指定为float类型return 0;
}

虚拟类型使用template关键词定义,也可以使用class定义,可以在<>符号内定义多个虚拟类型,不同虚拟类型使用,符号隔开,但是每个定义的虚拟类型都必须使用,否则编译报错。

函数模板内可以使用多个虚拟类型,执行函数模板时需要为其内部虚拟类型指定具体类型,当多次执行函数模板并为虚拟类型设置不同的具体类型时,编译器会将函数模板编译为多个函数,分别使用不同的指令处理数据,上述代码中的add函数实际上会被编译器编译成两个函数,分别使用整数运算指令和浮点数运算指令处理数据,模板只是简化了程序员的工作量,并没有减少程序编译后的代码量。

成员函数模板

#include <iostream>
class math
{
public:template <typename T>    //定义虚拟类型T add(T t1, T t2) const{return t1+t2;}
};
int main()
{math math1;printf("%d\n", math1.add(1, 2));printf("%f\n", math1.add(0.1f, 0.2f));return 0;
}

类模板

成员数据使用虚拟类型的类称为类模板。

#include <iostream>
template <typename T>
class math
{
private:T a,b;public:math(T t1, T t2){a = t1;b = t2;}T add() const{return a+b;}
};
int main()
{math<int> math1(1, 2);         //创建对象时需要使用<>符号设置数据类型printf("%d\n", math1.add());math<float> math2(0.1, 0.2);printf("%f\n", math2.add());return 0;
}

成员数组模板

虚拟类型用于类成员数组时可以额外定义一个变量,此变量用于设置数组模板的长度,从而实现数组的类型、长度都在定义时临时确定。

#include <iostream>
template <typename T, int i>    //变量i设置数组长度
class array
{
private:T a[i];public://......
};
int main()
{array<int, 5> array1;      //成员数组类型为int,包含5个元素array<float, 6> array2;    //成员数组类型为float,包含6个元素return 0;
}


【符号重载】

在C++中可以借助operator关键词将语法中的某些符号、关键词当做函数名,从而重新定义此符号的功能,这种函数称为符号函数,调用符号函数执行时可以无需指定operator关键词,直接使用重载的符号即可,全局函数和成员函数都可以设置为符号函数。

使用符号函数会让代码更简洁,比如连接字符串函数使用+符号作为函数名,即可通过+符号连接两个字符串。


可重载的符号如下:

+  -  *  /  ++  --  %  <<  >>
&&  ||  !  &  |  ~  ^
<  >  ==  !=  >=  <=
=  +=  -=  *=  /=  %=  ^=  &=  |=  >>=  <<=
,  ()  []
->  ->*
new  delete  new[]  delete[]


符号重载注意事项:
1.只能使用C++语法中原有符号,不能使用C++语法没有的符号。
2.= () [] -> 这四种符号只能用于成员函数,不能用于全局函数。
3.重载不同符号时,函数可以设置的参数个数不同。
4.重载相同符号时,全局函数与成员函数可以设置的参数个数不同。
5.重载不同符号有不同的限制,比如:重载-符号不能计算两个double数据相加、重载%符号不能只有一个操作数、重载new的函数返回值只能是void类型指针。


重载 + 符号

重载+符号连接固定长度字符串对象,并返回连接结果。

#include <iostream>
class string
{
public:char strvar[100] = {0};/* operator+符号函数连接string对象 */string operator+(const string & conobj) const{string result;              //存储连接结果unsigned int strlen = 0;    //存储本类strvar空字符下标unsigned int conlen = 0;    //存储conobj.strvar空字符下标result.strvar[0] = 0;       //初始空字符/* 查询本类strvar空字符下标,若没有空字符则当做不合规string对象处理,strlen = 0 */for(int i = 0; i < 100; i++){if(strvar[i] == 0){strlen = i;break;}}/* 查询conobj.strvar空字符下标 */for(int i = 0; i < 100; i++){if(conobj.strvar[i] == 0){conlen = i;break;}}/* result连接本类strvar */if(strlen != 0){result = *this;}/* result连接conobj.strvar */if(conlen != 0){if(strlen == 0){result = conobj;}else{for(int i = 0; strlen<99 && i<=conlen; i++){result.strvar[strlen] = conobj.strvar[i];strlen++;}result.strvar[99] = 0;    //确保末尾元素是空字符}}return result;}/* 重载operator+符号函数,连接字符串 */string operator+(const char * conobj) const{string result;unsigned int strlen = 0;unsigned int conlen = 98;    //若字符串长度超标,则最多使用99个字符result.strvar[0] = 0;/* 查询本类strvar末尾下标 */for(int i = 0; i < 100; i++){if(strvar[i] == 0){strlen = i;break;}}/* 查询conobj末尾下标,只需查询99个字节 */for(int i = 0; i < 99; i++){if(conobj[i] == 0){conlen = i;break;}}/* 连接本类strvar */if(strlen != 0){result = *this;}/* 连接conobj */if(conlen != 0){for(int i = 0; strlen<99 && i<=conlen; i++){result.strvar[strlen] = conobj[i];strlen++;}result.strvar[99] = 0;}return result;}
};
int main()
{string ali = {"阿狸"};string taozi = {"桃子"};string zoo = ali + taozi;      //调用ali.operator+函数,连接string对象printf("%s\n", zoo.strvar);zoo = zoo + "喜羊羊美羊羊";      //调用zoo.operator+函数,连接字符串printf("%s\n", zoo.strvar);return 0;
}


重载 = 符号

重载=符号修改动态长度字符串对象,字符串成员定义为私有,只能通过operator=符号函数修改。

#include <iostream>
#include <string.h>
class string
{
private:char * strvar;public:string(){strvar = new char;*strvar = 0;}string(const char * assobj){size_t asslen = strlen(assobj); strvar = new char[asslen+1];strcpy(strvar, assobj);strvar[asslen+1] = 0;     //末尾空字符}~string(){delete [] strvar;}/* 返回字符串地址 */const char * get() const{return strvar;}void operator=(const char *assobj){size_t asslen = strlen(assobj);/* 释放旧内存 */delete [] strvar;/* 申请新内存 */strvar = new char[asslen+1];/* 内存赋值 */strcpy(strvar, assobj);strvar[asslen+1] = 0;}
};int main()
{string zoo("阿狸");printf("%s\n", zoo.get());zoo = "喜羊羊";printf("%s\n", zoo.get());return 0;
}


 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

朗伯特球腔均匀光源积分球

均匀光源积分球&#xff0c;又称照度积分球或光度球、光通球&#xff0c;是光电测试中常用的一种工具。它是一个中空的球体&#xff0c;内壁涂有一层平整的漫反射材料&#xff0c;通常由金属或陶瓷制成。积分球的主要功能是收集光并将其作为散射光源或测量光源使用。 积分球的工…

LeetCode54:螺旋矩阵

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 解题思想 模拟 循环一圈 后 跳出循环的条件&#xff1a;左边界&#xff1e;右边界 或者 上边界 > 下边界 代码 class Solution { public:vect…

突然发现一个很炸裂的平台!

平时小孟会开发很多的项目&#xff0c;很多项目不仅开发的功能比较齐全&#xff0c;而且效果比较炸裂。 今天给大家介绍一个我常用的平台&#xff0c;因含低代码平台&#xff0c;开发相当的快。 1&#xff0c;什么是低代码 低代码包括两种&#xff0c;一种低代码&#xff0c;…

Publii和GitHub:搭建个人网站的完美组合

在数字时代&#xff0c;拥有一个个人网站已经非常普遍了&#xff0c;但是&#xff0c;很多人因为技术难题而望而却步。现在&#xff0c;有了Publii&#xff0c;这一切都将变得简单。Publii是一个静态网站生成器&#xff0c;它允许你在本地计算机上创建和管理内容&#xff0c;然…

实战|环信 Vue2 uniapp Demo重构焕新!经典再升级!

项目背景 当前环信 uni-app vue2 Demo 地址升级版本 Github 地址&#xff08;临时&#xff09; 原版本功能实现方式较混乱&#xff0c;代码逻辑晦涩难懂&#xff0c;不利于开发者参考或复用。此实战项目在确保原项目功能保留的情况下进行完全重写并新增大量功能&#xff0c;以…

JavaWeb - 3 - JavaScript(JS)

JavaScript(JS)官方参考文档&#xff1a;JavaScript 教程 JavaScript&#xff08;简称&#xff1a;JS&#xff09;是一门跨平台、面向对象的脚本语言&#xff0c;是用来控制网页行为的&#xff0c;它能使网页可交互&#xff08;脚本语言就不需要编译&#xff0c;直接通过浏览器…

简介:基于 OpenTiny 组件库的 rendereless 无渲染组件架构

在 HAE 自研阶段&#xff0c;我们实现的数据双向绑定、面向对象的 JS 库、配置式开发的注册表等特性&#xff0c;随着前端技术的高速发展现在已经失去存在的意义&#xff0c;但是在 AUI 阶段探索的新思路新架构&#xff0c;经过大量的业务落地验证&#xff0c;再次推动前端领域…

【网络层】IP多播技术的相关基本概念(湖科大慕课自学笔记)

IP多播 1&#xff1a;IP多播技术的相关基本概念 我们简单举例&#xff0c;如下图所示&#xff1a; 一共有60个主机要接受来自视频服务器的同一个节目&#xff0c;如果采用单播方式&#xff0c;则视频服务器要发送60份&#xff0c;这些视频节目通过路由器的转发&#xff0c;最…

IOS覆盖率报告info文件解读

一&#xff0c;IOS覆盖率报告的生成 在做前端精准测试的时候&#xff0c;对于iOS端&#xff0c;通常会做如下操作&#xff1a; &#xff08;1&#xff09;合并覆盖率数据 如下操作&#xff1a; xcrun llvm-profdata merge coverage_file1657885040728.profraw coverage_fil…

C语言第三十七弹---文件操作(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 文件操作 1、文件的随机读写 1.1、fseek 1.2、ftell 1.3、rewind 2、文件读取结束的判定 2.1、被错误使用的 feof 3、文件缓冲区 总结 1、文件的随机读写…

typescript学习(更新中)

目录 开发环境搭建类型如何声明有哪些类型编译配置文件 开发环境搭建 npm i -g typescripttsc检查是否安装成功 类型如何声明 // 先声明再赋值 let a: number a 1// 直接赋值 let b 1function sum(a: number, b: number): number {return a b } console.log(sum(1, 2))有…

VSCode搭建ARM开发环境

为了构建Cortex M系列单片机免费开源的开发环境&#xff0c;网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式&#xff0c;下面记录环境搭建的流程。 我这边的PC环境为 WIN7专业版64bit。 需要用到的工具 Visual Studio CodeSTM32CubemxARM GCC 交叉编译工具链&#x…

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录&#xff0c;在本节博客中我将详细谈论设计循环队列的思路&#xff0c;并给出代码&#xff0c;有需要借鉴即可。 题目&#xff1a;LINK 循环队列是线性表吗&#xff1f;或者说循环队列是线性结构吗&#xff1f; 对于这个问题&#xff0c;我们来看一下线…

Vue 项目性能优化指南:提升应用速度与效率

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Qt插件之输入法插件的构建和使用(二)

文章目录 主键盘搭建Google开源引擎音节分割工具类参考项目下载搭建好各个基础控件之后,就可以开发输入法的主界面和引擎了,这也是输入法的核心。 主键盘搭建 输入法的主界面本质上是一个QStackedWidget容器,将各个类型的输入键盘插入到容器中,然后根据业务需要切换不同的…

图机器学习(4)-面向连接层面的人工特征工程

0 问题定义 通过已经连接去猜未知连接&#xff1a; 有两个思路&#xff1a; &#xff08;1&#xff09;直接提取link的特征&#xff0c;把link变成D维向量&#xff1b; &#xff08;2&#xff09;把link两端节点的D维向量拼在一起&#xff0c;缺点&#xff1a;丢失了link本身…

蓝桥省赛倒计时 35 天-线性 dp 练习

文章目录 数学三角形最长上升子序列 数学三角形 思路&#xff1a;就是下一层通过上一层的条件转移过来&#xff0c;注意数可以是负数&#xff0c;所以边界得取-INF&#xff0c;这样求上层 max 的时候不会被初始化的数如 0 影响。 #include<bits/stdc.h> using namespace…

md5绕过

文章目录 \\和\\\md5数组绕过科学计数法绕过双md加密md5碰撞Hash长度攻击 下面会以同一道题给大家演示&#xff1a; (题目来源与nssctf) 和 在php代码中我们会看到和&#xff0c;虽然两个都是表示相等&#xff0c;但是在细节上会有所部区别 &#xff1a;是弱比较&#xff0c;只…

美团春招编程第一场第三题

美团春招编程第一场第三题 题目 解答 思路-暴力解法 pair中存储从原点到包含当前元素的0,1数量&#xff0c;得到二维数组mat; 从头到尾遍历尺寸为i*i的矩形&#xff0c;计算完美矩形数量 #include <iostream> #include <vector> using namespace std;int main()…

【项目】Boost 搜索引擎

文章目录 1.背景2.宏观原理3.相关技术与开发环境4. 实现原理1.下载2.加载与解析文件2.1获取指定目录下的所有网页文件2.2. 获取网页文件中的关键信息2.3. 对读取文件进行保存 3.索引3.1正排与倒排3.2获取正排和倒排索引3.3建立索引3.3.1正排索引3.3.2倒排索引 4.搜索4.1 初始化…