C++ 字符串也能做下标?之 [ ] 运算符重载

C/C++ 下标运算符subscript、后缀表达式、正负下标 提问:如果我们要获得a数组的第二个元素,请问一下那种方式可以达到要求。 int a[] = { 1,2,3,4,5,6 }; cout << a[1] << endl; cout << *(a+1) << endl; cout << 1[a] << endl; cout << (1)[a] << endl; 答案是都可以。 首先,ar[i]和*(ar+1)这两个表达式都是等价的,这里就不再多说了,而1[a] 与 阅读详情

[ ] 运算符重载,在一些特定的场合会有奇效;
具体方法和关系运算符,赋值运算符等都是一样的;

它有两种形式:
字符串下标法 和 数字下标法

我将举一个例子详细说明 [ ] 运算符重载会在哪些场合使用,后续又该如何优化…

需求:
1.定义一个Boy类,里面有private成员name, age, salary 和 coefficient;
2.根据Boy类定义出两个对象boy1 和 boy2 并赋值:
Boy boy1(“张三”, 21, 20000, 10);
Boy boy2(“李四”, 22, 22000, 8);
3. 利用字符串下标法 和 数字下标法将他们打印出来
4. 将代码进行优化


1.定义一个Boy类,里面有private成员name, age, salary 和 coefficient;

Boy.h

#pragma once
#include <string>

class Boy {
public:
	Boy(const char *name = "无名", int age = 0, int salary = 0, int coefficient = 0);
	~Boy();

	char *getName() const;
	
	// 下标运算符重载
	const int operator[](std::string index) const;	// 字符串下标
	int operator[](int index) const;			// 数字下标

private:
	char *name;
	int age;
	int salary;
	int coefficient;	// 系数
};

Boy.cpp

#include "Boy.h"

Boy::Boy(const char *name, int age, int salary, int coefficient) {
	this->name = new char[strlen(name)+1];
	strcpy_s(this->name, strlen(name)+1, name);

	this->age = age;
	this->salary = salary;
	this->coefficient = coefficient;
}

Boy::~Boy() {
	if (name) {
		delete[] name;
	}
}

char* Boy::getName() const {
	return name;
}

// 字符串下标
const int Boy::operator[](std::string index) const {
	if (index == "age") {
		return age;
	} else if (index == "salary") {
		return salary;
	} else if (index == "coefficient") {
		return coefficient;
	} else {
		return -1;
	}
}

// 数字下标
int Boy::operator[](int index) const {
	if (index == 0) {
		return age; 
	} else if (index == 1) {
		return salary;
	} else if (index == 2) {
		return coefficient;
	} else {
		return -1;
	}
}

2.根据Boy类定义出两个对象boy1 和 boy2 并赋值:
Boy boy1(“张三”, 21, 20000, 10);
Boy boy2(“李四”, 22, 22000, 8);

#include <iostream>
#include "Boy.h"

using namespace std;

int main(void) {
	Boy boy1("张三", 21, 20000, 10);
	Boy boy2("李四", 22, 22000, 8);


	******3. 利用字符串下标法 和 数字下标法将他们打印出来******
	/********************************************************/
	cout << "字符串下标:" << endl;
	cout << "name = " << boy1.getName() << endl;
	cout << "age = " << boy1["age"] << endl;
	cout << "salary = " << boy1["salary"] << endl;
	cout << "coefficient = " << boy1["coefficient"] << endl;

	cout << endl << "数字下标:" << endl;
	cout << "name = " << boy2.getName() << endl;
	cout << "age = " << boy2[0] << endl;
	cout << "salary = " << boy2[1] << endl;
	cout << "coefficient = " << boy2[2] << endl;

	system("pause");
	return 0;
}

运行截图:

在这里插入图片描述

4. 将代码进行优化

代码中还有那些地方可以进行优化的呢?

其实可以优化的地方就在下标当中:

1.字符串下标中,下标是常量字符串,如果在写代码时写错了,编译器并不会报错,也可以正确运算,只是会找不到对应的数据,最总返回-1;而且如果上百万行代码,使用字符串常量下标的话,如果有一处需要修改,那么需要把这上百万代码都该掉,这是一个很大的工作量,所以,优化应使用宏定义最佳。

2.数字下标中,下标是数字,不可读,看着数字0, 1, 2… 看代码的人并不知道这些数字代表的是什么意思,所以,优化应使用枚举类型最佳。

一、字符串下标优化

在Boy.h中定义宏定义:

#define AGE_KEY			"age"
#define SALARY_KEY		"salary"
#define COEFFICIENT_KEY "coefficient"

二、数字下标优化

在Boy.h中定义枚举类型

typedef enum {
	AGE,
	SALARY,
	COEFFICIENT
};

Boy.h 代码优化

#pragma once
#include <string>

#define AGE_KEY			"age"
#define SALARY_KEY		"salary"
#define COEFFICIENT_KEY "coefficient"

typedef enum {
	AGE,
	SALARY,
	COEFFICIENT
};

class Boy {
public:
	Boy(const char *name = "无名", int age = 0, int salary = 0, int coefficient = 0);
	~Boy();

	char *getName() const;

	// 下标运算符重载
	const int operator[](std::string index) const;	// 字符串下标
	int operator[](int index) const;			// 数字下标

private:
	char *name;
	int age;
	int salary;
	int coefficient;	// 系数
};

Boy.cpp 代码优化

#include "Boy.h"

Boy::Boy(const char *name, int age, int salary, int coefficient) {
	this->name = new char[strlen(name)+1];
	strcpy_s(this->name, strlen(name)+1, name);

	this->age = age;
	this->salary = salary;
	this->coefficient = coefficient;
}

Boy::~Boy() {
	if (name) {
		delete[] name;
	}
}

char* Boy::getName() const {
	return name;
}

const int Boy::operator[](std::string index) const {
	if (index == AGE_KEY) {
		return age;
	} else if (index == SALARY_KEY) {
		return salary;
	} else if (index == COEFFICIENT_KEY) {
		return coefficient;
	} else {
		return -1;
	}
}

int Boy::operator[](int index) const {
	if (index == AGE) {
		return age; 
	} else if (index == SALARY) {
		return salary;
	} else if (index == COEFFICIENT) {
		return coefficient;
	} else {
		return -1;
	}
}

main函数代码优化

#include <iostream>
#include "Boy.h"

using namespace std;

int main(void) {
	Boy boy1("张三", 21, 20000, 10);
	Boy boy2("李四", 22, 22000, 8);

	/*cout << "字符串下标:" << endl;
	cout << "name = " << boy1.getName() << endl;
	cout << "age = " << boy1["age"] << endl;
	cout << "salary = " << boy1["salary"] << endl;
	cout << "coefficient = " << boy1["coefficient"] << endl;

	cout << endl << "数字下标:" << endl;
	cout << "name = " << boy2.getName() << endl;
	cout << "age = " << boy2[0] << endl;
	cout << "salary = " << boy2[1] << endl;
	cout << "coefficient = " << boy2[2] << endl;*/

	cout << "字符串下标:" << endl;
	cout << "name = " << boy1.getName() << endl;
	cout << "age = " << boy1[AGE_KEY] << endl;
	cout << "salary = " << boy1[SALARY_KEY] << endl;
	cout << "coefficient = " << boy1[COEFFICIENT_KEY] << endl;

	cout << endl << "数字下标:" << endl;
	cout << "name = " << boy2.getName() << endl;
	cout << "age = " << boy2[AGE] << endl;
	cout << "salary = " << boy2[SALARY] << endl;
	cout << "coefficient = " << boy2[COEFFICIENT] << endl;

	system("pause");
	return 0;
}

运行截图:

在这里插入图片描述

完美运算, 而且优化也完美!

使用 [ ] 运算符重载的优点: 可以使代码更可读。


总结:

1.在写代码时,应尽量避免常量,使用宏定义代替它;
2.写代码能优化尽量优化,这时初级程序员和高级程序员的分水岭;
3.返回值类型不同不能重载:
在代码中,我并没有把name也写入[ ] 重载运算函数中,也并没有独立写一个,
const int operator[ ] (std::string index) const;
const std::string operator[ ] (std::string index) const;
这样写会报错的,编译器不允许这样写,这是一个的注意的地方。

C++初阶讲解—运算符重载汇总+实例(下) 在实际开发中,我们应该同时提供以上两种形式,这样做是为了适应 const 对象,因为通过 const 对象只能调用 const 成员函数,如果不提供第二种形式,那么将无法访问 const 对象的任何元素。运算符重载其实就是定义一个函数,在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数。也就是说,运算符重载是通过函数实现的,它本质上是函数重载。运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,简化操作 让已有的运算符 适应不同的数据类型。不仅可以访问元素,还可以修改元素。 阅读详情

相关推荐

C++ 运算符与函数的重载

函数的重载: 参数个数、类型或顺序不同函数都可以当做不同的函数来进行声明与使用 (函数的类型不能作为判断依据); 举个例子:Print(int X)和Print(int X, int Y) 表示的是两个函数,这种使用方法就叫做函数的重载; 运算符的重载 (本文主要探讨) : 1> 一元运算符:!、++/--、-(负号) (文章最后介绍单目运算符的重载) 2> 二元运...

⚡ 4708

C++ 数组指针下标的理解【个人学习笔记用】

一、C++中传递参数的三种方法 1. 直接按值传递 形如: int fun1(int a){ printf(a); } 该方法会在调用函数时把传入的参数copy一份后在函数中进行操作,不会影响到原来的参数。 2. 指针(地址)传递 形如: int fun1(int *a){ printf(*a); } 将参数的地址(指针)传进来,函数的操作会直接影响到原参数。函数内部使用时候需要取值操作,如 *a 3.引用传递 形如: int fun1(int &a){ printf(a); }

qq_50031809的博客 5608

C++运算符重载提高

运算符重载提高赋值运算符重载 (operator=)数组下标运算符 (operator[])自定义数组类函数调用符号 (operator () )不可重载 && 和 || 操作符自定义字符串类 赋值运算符重载 (operator=) 用一个己有对象,给另外一个己有对象赋值。两个对象均己创建结束后,发 生的赋值行为。 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class

log_Li的博客 305

【C++代码】找出字符串中第一个匹配项的下标,重复的子字符串--代码随想录

本题是KMP 经典题目。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。KMP主要应用在字符串匹配上。主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。所以如何记录已经匹配的文本内容,是KMP的重点,也是next数组肩负的重任。next数组就是一个前缀表(prefix table)。前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。为了清楚的

白水空空 663

C++下标运算符详解

在实际开发中,我们应该同时提供以上两种形式,这样做是为了适应 const 对象,因为通过 const 对象只能调用 const 成员函数,如果不提供第二种形式,那么将无法访问 const 对象的任何元素。我们知道,有些较老的编译器不支持变长数组,例如 VC6.0、VS2010 等,这有时候会给编程带来不便,下面我们通过自定义的 Array 类来实现变长数组。,编译器不管实际上有没有修改对象,只要是调用了非 const 的成员函数,编译器就认为会修改对象(至少有这种风险)。不仅可以访问元素,还可以修改元素。

shiwei0813的博客 830

29、C++ 运算符重载:深入探索与实践

本博文深入探讨了 C++ 中的运算符重载机制,涵盖了算术运算符、比较运算符、下标运算符等多种运算符的重载方法。通过多个示例代码,详细讲解了如何在自定义类中实现如加法、字符串拼接、距离比较、数组安全访问等功能。同时,还介绍了运算符重载的最佳实践和注意事项,帮助开发者编写更加高效、简洁和易于维护的代码。

q9w8e7r6t5的博客 115

JAVA11-String中常用的一些方法

String类中的构造方法 char[] cs={'今','天','好','闷'}; String a=new String(cs); System.out.println(a);//今天好闷 String b=new String(cs, 1, 2); System.out.println(b);//天好 byte[] bs={97,98,99,100,101}; String c=new String(bs); System.out.printl

xc_init的博客 453

C++运算符重载与自定义数组访问

本文深入探讨了C++中运算符重载的概念及其应用。通过字符串和距离类的示例,展示了如何重载运算符来实现特定功能。同时,介绍了如何通过重载下标运算符[]来创建安全数组,以及如何通过引用返回值来优化数据访问。

weixin_42518874的博客 432

【C++】运算符重载案例 - 字符串类 ② ( 重载 等号 = 运算符 | 重载 数组下标 [] 操作符 | 完整代码示例 )

一、重载 等号 = 运算符 1、等号 = 运算符 与 拷贝构造函数 2、重载 等号 = 运算符 - 右操作数为 String 对象 3、不同的右操作数对应的 重载运算符函数 4、重载 等号 = 运算符 - 右操作数为 字符串指针 二、重载 下标 [] 运算符 三、完整代码示例 1、String.h 类头文件 2、String.cpp 类实现 3、Test.cpp 测试类 4、执行结果

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 2240

ComfyUI面部修复FaceDetailer保姆级教程:从模型选择到参数调优全解析

本文提供ComfyUI面部修复FaceDetailer的保姆级教程,深度解析从模型选择到参数调优的全过程。针对常见的五官模糊、肤色不均等问题,详细对比了BBox与Segm检测器的优劣,并给出SD1.5与SDXL模型的核心参数联动策略与实战方案,帮助用户精准掌控AI绘画中的面部修复效果。

weixin_29073241的博客 472

MLC-LLM框架在安卓设备上的模型编译与部署全流程解析

本文详细解析了如何利用MLC-LLM框架在安卓设备上编译与部署大语言模型。从环境搭建、模型获取与量化编译,到最终的安卓应用打包与调试,提供了完整的实战流程。重点介绍了如何通过MLC-LLM将大型模型优化为适合移动端运行的格式,实现本地、低延迟、隐私安全的AI应用部署。

weixin_29251337的博客 475

C++学习——重载下标运算符

C++重载下标运算符

MaoSiri的博客 766

使用Tansformer分割三维腹部多器官--UNETR实战

不会 transformer 没关系,本教程开箱即用。Tina姐总算对transformer下手了,之前觉得难,因为刚开始学序列模型的时候就没学会。然后就一直排斥学transformer。这两周没什么事,加上MONAI有现成的教程,就打算先跑通后,再学理论。然后,顺利的跑通了代码,再学了一周理论,发现它也不过如此嘛,入门还是很容易的。有同学想了解的transformer的话,可以先看完这个实战教程,如果感兴趣,后续会出一个transformer入门路线。利用纯Transformers作为编码器来学习输入量的

Tina姐的博客 1万+

5分钟用运算符重载实现自定义字符串类

通过这个MyString的小案例,我们既理解了重载机制的工作原理,又体验了快速原型开发的乐趣。返回的新对象应该包含拼接后的结果,这个过程需要仔细处理内存分配和字符拷贝的顺序。首先创建MyString类的骨架,包含私有字符指针成员和记录长度的变量。最近在复习C++的运算符重载特性时,发现通过这个功能可以快速验证一些面向对象的设计思路。整个过程就像在使用标准库的string类一样流畅,但背后是我们自己实现的逻辑。上实践这个案例特别方便,不需要配置复杂的开发环境,打开网页就能立即编写和运行代码。

GoldenleafLynx28的博客 570

《揭秘 BME688人工智能压力湿度温度气体传感器:气体检测的多面能手》:此文为AI自动生成

BME688 是博世推出的一款具有人工智能和集成高线性度高精度压力、湿度、温度传感器的气体传感器,专为移动和联网应用开发,尺寸紧凑且低功耗。BME688 作为一款先进的传感器,在多个领域展现出卓越的性能。它采用了坚固而紧凑的 3.0 x 3.0 x 0.9 mm³ 封装,这种小巧的尺寸使其能够轻松应用于对空间要求严格的移动设备和联网应用中。同时,低功耗的特性也使得它在能源有限的环境下能够长时间稳定运行。

zheng_ruiguo的专栏 1931

IMEI引起的无法驻网问题

问题不复杂,场景很简单,如上图,UE在进行LTE attach过程时,在送完NAS security mode complete后,就立刻收到了网络attach reject 带cause 6 Illegal ME,根据协议描述这个cause 代表ME不被网络可接受,例如ME在禁止名单或者黑名单中就会有这种cause。然而前方在报这个问题的时候,也是知道SIM卡和手机IMEI在运营商那边没能成功绑定,然后才报的问题,要查看手机是不是有问题...... 告诉前方原因后,还认为是手机问题,告知要继续查。

asd199086的博客 1426

C++赋值运算符、函数调用运算符、下标运算符(“=”、“()”、“[]”)重载

转自 http://blog.163.com/hbu_lijian/blog/static/126129153201211545633152/ //对于一般的类,如Complex类,系统会默认重载赋值运算符,但有些类对于系统默认的赋值运算符无法满足要求,这个时候就要用户自己来重载赋值运算符。另外,赋值运算符只能用成员函数重载,不能用友元函数重载。 #include #include

smallgyy的专栏 1343

【论文汇总】Diffusion Models视频生成/视频编辑/可控视频生成/跨模态视频生成

本文总结了Diffusion Models视频生成领域相关的工作,目前共收录142篇,持续更新中。

沉迷单车的追风少年 1672

MyString 类中的 [ ] 运算符重载,返回char

这是一个类MyString 类中的私有数据成员:其他函数成员和数据成员不全 指针 char * ptr; 要求重载: ptr[i] 返回类型是char class MyString{ char *ptr; public: char operator[](int i); }; int main(){ MyString s1; for(int i=s4.size()-1;i>=0;i--) cout<<s4[i]; cout<<e...

m0_67695275的博客 200

畅游Diffusion数字人(20):FLAME代码解读与实现

​ 之前的博客《畅游Diffusion数字人(17):更强大的人脸和表情表达方法 FLAME:Learning a model of facial shape and expression》讲解了FLAME的原理,这篇博客主要讲解一下FLAME的代码实现。

沉迷单车的追风少年 1131

STM32(HAL库)驱动OLED

通过STM32F103C8T6单片机采用HAL库方式对0.96寸OLED(IIC通讯)屏幕进行驱动。

weixin_44597885的博客 8801

C++学习笔记 -重载下标运算符_hawkol_新浪博客

//重载下标运算符 #include using namespace std; class mystring { public: mystring(char *pc) { strcpy(c,pc); } char operator[](int i)//下标运算符重载 { if(c[i]>='a'&&c[i]<='z')//判断是否是小写 ...

hawkol的专栏 138

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++重载运算符

#include&lt;iostream&gt; #include&lt;iomanip&gt; #include&lt;string&gt; using namespace std; //重载运算符的意义: //复数类:繁琐的调用,冗余的参数列表 class CComplex{ private: int iReal;//实部 int iImg;//虚部 public: CComple...

CherishPrecious的博客 212

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++下标运算符 []

#include #include #include using std::cout; using std::endl; using std::string; class CharArr { public: CharArr(int size) :_len(size) ,_pstr(new char[_len]){ } ~CharArr() {

田航语 2724

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

运算符重载

运算符重载: operator关键字用来重载运算符 1、概念 1)本质是一个函数,函数名的组成方式是:operator + 要重载的运算符   运算符的重载函数可以写到类的内部,但内外只能有一个(尽量写内部,内外的实现方式由于传参方式不同实现代码不同在一些复杂的运算时会有不同) 2)有部分运算符不能重载   .   ::    .*    ?:   sizeof 3)重载步骤:首先写出函

yizhe0731的博客 330

Problem A: 自定义字符串的下标运算

Description 定义类MyString,由长度不超过100的字符串组成。重载其下标运算符: int operator[](char ch) 用于重复求指定字符ch在串中的下标。 重载其输入运算符,用于输入字符串。 Input 输入一个不含空白符的字符串(长度不超过100个)和一个字符。 Output 指定字符在字符串中的所有位置。 Sample Input babababaab a Sample Output 1 3 5 7 8 -1 HINT 下标运算符中

weixin_52540973的博客 493
上一篇: C++ 关系运算符重载与赋值运算符重载
下一篇: C++ 类型运算符重载
cpp_learners
博客等级 码龄7年 1526粉丝 274原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值