19.C++-(=)赋值操作符、初步编写智能指针

(=)赋值操作符

  • 编译器为每个类默认重载了(=)赋值操作符
  • 默认的(=)赋值操作符仅完成浅拷贝
  • 默认的赋值操作符和默认的拷贝构造函数有相同的存在意义

(=)赋值操作符注意事项

首先要判断两个操作数是否相等

返回值一定是 return *this; 返回类型是Type&型,避免连续使用=后,出现bug

比如:

class Test{int *p;Test(int i){p=new int(i);}
Test
& operator = (const Test& obj){if(this!=obj){delete p;p=new int(*obj.p);}return *this;} };

 

注意:指针对象之间赋值是不会调用(=)复制操作符的

 

编译器默认提供的类函数

包括了:构造函数,析构函数,拷贝构造函数, (=)赋值操作符

 

智能指针

智能指针的由来

在以前C程序里,使用malloc()等函数动态申请堆空间时,若不再需要的内存没有被及时释放,则会出现内存泄漏,若内存泄漏太多,则会直接导致设备停止运行,特别是嵌入式设备,可能有些设备一上电就要运行好几个月.

在C++里,为了减少内存泄漏,所以便引出了智能指针

介绍

  • 智能指针实际上是将指针封装在一个类里,通过对象来管理指针.
  • 构造函数时,通过对象将指针传递进来,指针可以是缺省值.
  • 然后构造-> ” “ * ” “ = 操作符重载,让这个对象拥有指针的特性.
  • 最后通过析构函数,来释放类里的指针.

 

注意

  • 智能指针只能指向堆空间中的对象或者变量
  • 并且一片空间最多只能由一个智能指针标识(因为多个指向地址相同的智能指针调用析构函数时,会出现bug)
  • ->和*都是一元操作符,也就是说不能带参数

比如ptr->value的->:

当ptr的类型是普通指针类型时,等价于:(*ptr).mem

当ptr的类型是时,等价于:(ptr.operator->())->value    等价于: ( *(ptr.operator->()) ).value

所以->操作符函数的返回类型是type*,返回值是一个指针变量本身(不带*)

具体参考: https://segmentfault.com/q/1010000004620896

 

接下来个示例,指向一个int型的智能指针

#include <iostream>using namespace std;class Point{
int *p; public:Point(int *p=NULL){this->p = p;}int* operator -> (){return p;}int& operator *(){return *p;}~Point(){cout<<"~Point()"<<endl;delete p;} };int main() { for(int i=0;i<5;i++) {Point p=new int(i);cout <<*p<<endl;}return 0; }

 

运行打印:

0
~Point()
1
~Point()
2
~Point()
3
~Point()
4
~Point()

 

从结果可以看到, Point p每被从新定义之前,便会自动调用析构函数来释放之前用过的内存,

这样便避免了野指针的出现

 

接下来,我们继续完善上面代码,使它能够被赋值.

#include <iostream>
using namespace std;class Point{int *p;public:Point(int *p=NULL){this->p = p;} bool isNULL(){return (p==NULL);}int* operator -> (){return p;}  
int& operator *(){return *p;}Point& operator = (const Point& t){cout<<"operator =()"<<endl;if(this!=&t){delete p;p = t.p;const_cast<Point&>(t).p=NULL; //去掉const类型参数} return *this;}~Point(){cout<<"~Point()"<<endl;delete p;} };int main() { Point p=new int(2);Point p2;p2= p; //等价于 p2.operator= (p); cout <<"p=NULL:"<<p.isNULL()<<endl;*p2+=3; //等价于 *(p2.operator *())=*(p2.operator *())+3; //p2.operator *()返回一个int指针,并不会调用Point类的=操作符cout <<"*p2="<<*p2 <<endl;return 0; }

 

运行打印:

operator =()       p=NULL:1              // Point  p的成员已被释放*p2=5~Point()
~Point()

但是,还有个缺点,就是这个智能指针仅仅只能指向int类型,没办法指向其它类型. 

接下来继续修改,通过类模板来使这个智能指针能指向多种类型

#include <iostream>using namespace std;template <typename T>
class Point
{T *p;
public:Point(T *p){this->p = p; }bool isNULL(){return (p==NULL);}T* operator -> (){return p; } T& operator *(){return *p; } Point& operator = (const Point& t){cout<<"operator =()"<<endl;if(this!=&t){delete p;p = t.p;const_cast<Point&>(t).p=NULL;   //去掉const类型参数
              }         return *this;}~Point(){delete p;    } };int main()
{       Point<int> p1=new int(2); cout<<*p1<<endl; Point<float> p2=new float(3.56);  cout<<*p2<<endl;return 0;
}

运行打印:

2
3.56
~Point()
~Point()

 

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

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

相关文章

windows mysqldump 不成功 1049 1064 报错

1064 路径不对&#xff0c;需要cd选到mysql bin目录下 1049 在cmd里面不需要分号 以下是正确的 E:\phpStudy\PHPTutorial\MySQL\bin>mysqldump -uroot -proot db >db.sql 转载于:https://www.cnblogs.com/JANCHAN/p/9227388.html

学成在线--14.使用RabbitMQ完成页面发布

文章目录一.技术方案二.页面发布——消费方1.需求分析2.创建Cms Client工程1&#xff09;创建maven工程2&#xff09;配置文件3&#xff09;启动类3.RabbitmqConfig配置类4.定义消息格式5.PageDao1&#xff09;使用CmsPageRepository 查询页面信息2&#xff09;使用CmsSiteRepo…

对象模型中类与类间的关系

类与类之间通常有关联、聚集、泛化(继承)、依赖和细化4种关系 1.关联 关联表示两个类的对象之间存在某种语义上的联系。 (1) 普通关联 只要在类与类之间存在连接关系就可以用普通关联表示。普通关联的图示符号是连接两个类之间的直线&#xff0c;如下图所示。关联…

记忆讲师石伟华微信公众号2017所有文章汇总(待更新)

17-10-24-不胜光荣的记忆 17-10-26-每日一个超长英文单词&#xff08;2&#xff09; 17-10-27-每日一个超长英文单词&#xff08;3&#xff09; 17-10-28-每日一个超长英文单词&#xff08;4&#xff09; 转载于:https://www.cnblogs.com/bakblog/p/9228096.html

Log4J日志配置详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、Log4j简介 Log4j有三个主要的组件&#xff1a;Loggers(记录器)&#xff0c;Appenders (输出源)和Layouts(布局)。这里可简单理解为日…

中文编码杂谈

编码问题的例子 在windows自带的notepad&#xff08;记事本&#xff09;程序中输入“联通”两个字&#xff0c;保存后再次打开&#xff0c;会发现“联通”不见了&#xff0c;代之以“”的乱码。这是windows平台上典型的中文编码问题。即文件保存的时候是按照ANSI编码&#xff…

Java NIO (十四)NIO 和 IO 的区别和适用场景分析

在研究Java NIO和IO API时&#xff0c;很快就会想到一个问题&#xff1a; 什么时候应该使用IO&#xff0c;什么时候应该使用NIO&#xff1f; 在本文中&#xff0c;我将尝试阐明Java NIO和IO之间的区别&#xff0c;它们的用例以及它们如何影响代码的设计。 ###Java NIO和IO之间的…

面向对象三种模型之间的关系

功能模型指明了系统应该“做什么”&#xff1b;动态模型明确规定了什么时候(即在何种状态下接受了什么事件的触发)做&#xff1b;对象模型则定义了做事情的实体。在面向对象方法学中&#xff0c;对象模型是最基本最重要的&#xff0c;它为其他两种模型奠定了基础&#xff0c;人…

android node

pkg install nodejs-current转载于:https://www.cnblogs.com/insight0912/p/9231342.html

springmvc 中@Controller和@RestController的区别

1.Controller, RestController的共同点 都是用来表示Spring某个类的是否可以接收HTTP请求 2.Controller, RestController的不同点 Controller标识一个Spring类是Spring MVC controller处理器 RestController&#xff1a; a convenience annotation that does nothing more …

easyUI 日期控件修改...

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 个人觉得easyUI挺好用的。 它的中文文档地址&#xff1a; http://www.zi-han.net/case/easyui/ 日期本来效果是这样的&#xff1a; 改…

面向对象分析的三个模型与5个层次

在面向对象分析中&#xff0c;主要由对象模型、动态模型和功能模型组成。对象模型是最基本、最重要、最核心的。 面向对象建模得到的模型包含系统的3个要素&#xff0c;即静态结构(对象模型)、交互次序(动态模型)和数据变换(功能模型)。解决的问题不同&#xff0c;这3个子模型…

学成在线--15.课程计划查询

文章目录一.需求分析二.页面原型1.tree组件介绍2.webstorm配置jsx三.API接口1.数据模型2.自定义模型类3.接口定义四.sql语句五.服务器端1.Dao1&#xff09;Mapper接口2&#xff09;Mapper映射文件2.Service3.Controller4.测试六.前端1.Api方法2.Api调用1&#xff09;定义查询课…

团队作业-项目答辩

1. 王书磊 1600802063 http://www.cnblogs.com/wsl-1117/ 刘令斌 1600802017 http://www.cnblogs.com/liulingbin/ 许浩然 1600802066 https://www.cnblogs.com/xuhaoran1/ 成明龙 1600802038 http://www.cnblogs.com/CMLCML/ 2这是我们的效果图. 3.&#xff08;1&#xff09;修…

Java构造和解析Json数据的两种方法详解一

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在www.json.org上公布了很多JAVA下的json构造和解析工具&#xff0c;其中org.json和json-lib比较简单&#xff0c;两者使用上差不多但还是…

面向对象方法开发的方法

面向对象分析首要的工作&#xff0c;是建立问题域的对象模型。 这个模型描述了现实世界中的“类与对象”以及它们之间的关系&#xff0c;表示了目标系统的静态数据结构。静态数据结构对应用细节依赖较少&#xff0c;比较容易确定。因此&#xff0c;用面向对象方法开发绝大多数…

程序员编程需要多少个小时?

Michael Arrington曾发表一篇博文说&#xff0c;创业者必须加倍的努力工作&#xff0c;甚至不惜趴在办公桌上睡觉&#xff0c;这样才能成功。对此&#xff0c;我并不赞同其观点&#xff0c;我看了很多评论都是关于这样工作会适得其反&#xff0c;不但没有获得成功&#xff0c;相…

事务以及@Transcational注解

文章目录1.事务的概念2.事务的四个特性3.关于Transcational注解的理解4.使用场景5.举例6.编程式事务管理7.相关知识1.事务的概念 事务&#xff0c;是指作为单个逻辑工作单元执行的一系列操作&#xff0c;结果只有成功和失败两种&#xff0c;要么全部成功(全部提交)&#xff0c…

提高代码复用率

由于现在的互联网企业业务比较繁忙&#xff0c;导致产品狗不停地提需求&#xff0c;还总是改来改去&#xff0c;最后留给程序猿的时间少之又少。程序猿也不是吃素的&#xff0c;干脆直接copy一下代码随便搞一下实现功能就行&#xff0c;也谈不上所谓的精心设计了。这样的确是缩…

java 对 redis 的基本操作

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、server端安装 1、下载https://github.com/MSOpenTech/redis 可看到当前可下载版本&#xff1a;redis2.6 2、安装 1&#xff09;解压…