电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
适合具备 C 语言基础的 C++ 入门教程(四)
分 享
扫描二维码分享
适合具备 C 语言基础的 C++ 入门教程(四)
C++
wenzi 嵌入式软件
关注
发布时间: 2021-02-18
丨
阅读: 414
# 前言 在上一则教程中,我们讲述了重载运算符中前 `++`和后`++`的重载函数的实现,阐述了在 `C++`中可以将运算符进行重载的方法,这种方法大大地便利了程序员编写代码,在接下来地叙述中,我们将着重讲述运算发重载时地一些更为细致地内容,其中就包括当重载地运算符返回值为引用和非引用两种状态时,代码执行效率地高低以及采用在类内实现运算符重载函数的方法。 ## 返回值为引用和非引用的区别 在上述所示的类当中,增加一部分代码,加入析构函数以及拷贝构造函数,代码如下所示: ```c++ class Point { private: int x; int y; public: Point() { cout<<"Point()"<
x + p.x; n.y = this->y + p.y; return n; } } ``` 对比上述在类外面实现的代码,对于重载的运算符 `+`来说,只有一个形参了,而与其相加的另一个对象使用的是`this`来替代。依据这样的一种思路,我们继续将前 `++`和后 `++`重载的运算符函数进行改写,改写之后的代码如下所示: ```c++ class Point { private: int x; int y; public: /@@* Point p(1,2); ++p */ Point& operator++(void) { cout<<"operator++(void)"<
x += 1; this->y += 1; return *this; } /@@* Point p(1,2); p++; */ Point operator++(int a) { cout<<"operator++(int a)"<
x += 1; this->y += 1; return n; } }; ``` 结合上述的代码,我们再来编写主函数,主函数的代码如下所示: ```c++ int main(int argc, char ** argv) { Point p1(1,2); Point p2(2,3); Point m; Point n; cout << "begin" << endl; m = ++p1; /@@* m = p1.operator++(); */ cout << "m=" << m << "p1=" << p1 << endl; cout << "*********************" << endl; n = p2++; /@@* n = p2.operator++(0); */ cout << "n=" << n << "p2=" << p2 << endl; return 0; } ``` 上述代码中,注释掉的代码和没注释的代码前后是等价的,只是说注释掉的代码看起来更加直观,更加容易理解其背后的原理,而注释前的代码则更加简洁。这里额外说一点,`<<`的重载函数是不能够放到类内实现的,因为这个重载函数的形参不是 `Point`类的,所以其智能在类外才能实现。 上述中,叙述了在类内实现的重载运算符函数,接下来叙述一下 `=`运算符在类内实现的重载函数,我们以之前所说的 `Person`类来实现这个功能,`Person`类的代码实现如下所示: ```c++ class Person { private: char *name; int age; char *work; public: Person() { name = NULL; work = NULL; } Person(char *name, int age, char *work) { this->age = age; this->name = new char[strlen(name) + 1]; strcpy(this->name,name); this->work = new char[strlen(work) + 1]; strcpy(this->work, work); } /@@* 拷贝构造函数 */ Person(Person &p) { this->age = p.age; this->name = new char[strlen(p.name) + 1]; strcpy(this->name,p.name); this->work = new char[strlen(p.work) + 1]; strcpy(this->work, p.work); } ~Person() { if (this->name) delete this->name; if (this->work) delete this->work; } void PrintInfo(void) { cout << "name=" << name << "age=" << age << "work=" << work << endl; } } ``` 基于上述的代码,我们可以书写如下的主函数代码: ```c++ int main(int argc, char **argv) { Person p1("zhangsan", 18, "doctor"); Person p2; p2 = p1; } ``` 上述中,我们还没有将 `=`运算符进行重载,就使用了 `=`实现了实例化对象的运算,这样会存在一个什么问题呢,我们从源头来进行分析,`=`运算符执行的是值拷贝,那么在执行了上述语句之后,`p2`和`p1`之间的关系是这样的: ![image-20210208103422687](https://i.loli.net/2021/02/08/ywhv3zYKCaRjrXx.png) 通过上述所示的图片可以看出,如果不将 `=`进行重载,那么会让 `p1`和 `p2`的`name` 和 `work`指向同一块内存,这会造成什么问题呢,如果此时已经将 `p1`的内存释放掉了,而这个时候又要释放 `p2`的内存,这种情形就会出错,同一块内存不能够释放两次。 因此,就需要对 `=`运算符进行重载,重载的代码如下所示: ```c++ /@@* 注意此处的代码是在类里面实现的成员函数,这里省略的一部分代码 */ Person& operator=(Person &p) { if (this == &p) return *this; this->age = p.age; if (this->name) delete this->name; if (this->work) delete this->work; this->name = new char[strlen(p.name) + 1]; strcpy(this->name, p.name); this->work = new char[strlen(p.work) + 1]; strcpy(this->work, p.work); } ``` 这样子就会避免上述情况的出现,我们现在继续来书写主函数: ```c++ int main(int argc, char **argv) { Person p1("zhangsan", 18, "doctor"); cout<<"Person p2=p1" <
链接:https://pan.baidu.com/s/1BC55_QH-iV23-ON0v1OGSA > 提取码:iyf7
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
wenzi 嵌入式软件
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交