Effective C++学习第四天

条款11:在operator=中处理自我赋值的现象

           虽然我们在平时可能不会出现显示自我赋值的现象,当加入指针或者引用时,可能会出现不同的指针或引用指向同一对象(对象的不同别名),这时候我们就得考虑对象是否是同一个;考虑到要保证系统的自我赋值安全性和异常安全性的角度,可以采用的方案是:将原来的被赋值对象做一个副本,然后让被赋值对象指向复制对象,最后删除副本即可,代码如下:

        widget& widget::operator=(const widget & rhs){

                    bitmap *porig=pb;                          //pb为类widget的一个类型为bitmap的指针

                    pb=new  bitmap(*rhs.pb);

                    delete porig;

                    return *this;

          }

           最好的方法是采用copy and swap的方案,代码如下:(方案1采用传引用的方法,方案2采用传值的方法

       void swap(widget &rhs)  {....};    //交换rhs和*this的数据;

    方案1: widget &widget::operator=(const widget & rhs){              方案2: widget&widget::operator=(widget rhs)

                    widget temp(rhs);                                                      {   

                    swap(temp);                                                                                   swap(rhs);                                            

                   return *this;                                                                                    return *this;

      }                                                                                              }

条款12:复制对象时勿忘其每个成分

          当自己定义copy函数时(copy构造和copy assignment),编译器不再给我们提供新的copy函数,因此在拷贝的过程中,我们要确定所有的成员变量都被拷贝;

          当我们为class增添新的成员变量时,我们需要修改我们所有的copy函数,构造函数,采用继承的方式可以避免代码的过多修改,但是你必须保证base class的成员变量也被初始化,也就是在derived class的拷贝函数初始化列表或者函数体中调用base class的拷贝函数;如果不这样做,derived class在构造copy函数的时候会调用base class的default copy函数,但是base class的copy函数是被阻止的,因此此时编译器会报错;

         结论:当我们写一个自定义的copy函数的时候,确定几点:1)复制所有的local成员变量;2)调用所有base class内适当的copy函数;

            不要令copy assignment去调用copy构造函数;也不要让copy构造函数去调用copy assignment;

           当copy assignment和copy 构造函数有相近的代码时,可以把相同的代码变成新的成员函数,这样的函数通常为private且常命名为init;

条款13:以对象管理资源

             以singleton(单例模式)的factory function为例,函数返回的是一个heap-base的指针,用户在使用完这个对象之后需要把这个指针删除,如何保证这个指针所指向的资源被删除呢?可选用的方法是把:把资源放进对象中,利用C++的“析构函数自动调用机制”保证资源被释放;

             C++标准程序库中提供auto_ptr(类指针对象,也称为智能指针),其析构函数自动对其所指对象调用delete,常见的智能指针有unique_ptr,shared_ptr;weak_ptr;

            以对象管理资源的两个关键想法:1)获得资源后立刻放进管理对象内,实际上“以对象管理资源”的观念通常被称为“资源取得时机便是初始化时间(resource acquisition isinitialization RAII)”;2)管理对象运用析构函数确保资源被释放(在析构函数释放资源时,可能会出现异常,正确处理析构函数中抛出异常的情况);

            auto_ptr的特性是被销毁(调用copy函数时会发生)时自动删除它的所指之物,并将自己的指针指向nullptr,因此不要让对个auto_ptr指向同一个对象,如果这样可能会出现对象被删除一次以上;auto_ptr的性质是始终只有一个指针取得资源的唯一拥有权;

          auto_ptr的替代方案是:引用型计数指针(reference-counting smart pointer,RCSP),该指针特性就是持续追踪多个指针指向同一资源,并在无人指向该资源时释放资源,但是RCSP无法打破环形引用(也就是类中互相指向的问题,可用weak_ptr来解决这一现象);

         由于以对象管理资源在析构函数中执行的是delete而非delete[],因此动态分配的数组无法通过这种方式来实现内存释放,只能通过自己手工释放内存资源;

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

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

相关文章

Effective C++学习第五天

条款14:在资源管理类中小心copy行为当我们深入理解“资源取得时机是初始化时机(RAII)”概念,并以此作为“资源管理类”的核心时,我们可能会遇到将RAII对象复制的情况,一般有两种情况处理这个现象&#xff1…

Redis运维和开发学习笔记(2) redis持久化

Redis运维和开发学习笔记(2) redis持久化 文章目录Redis运维和开发学习笔记(2) redis持久化持久化持久化方式一:RDB触发~~的三种~~方式1. save命令2. bgsave配置触发机制RDB 总结持久化方式二:AOFAOF的三种策略三种策略的优缺点AOF重写机制持久化 redis将所有数据保存在内存中&…

Effective C++学习第六天

条款18:让接口更容易被正确使用,不易被误用设计接口的原则:正确性、高效性、封装性、维护性、延展性以及协议的一致性;设计原则:1)导入新类型来预防很多客户端的错误,多使用系统类型&#xff08…

Redis运维和开发学习笔记(4) Redis参数意义

Redis运维和开发学习笔记(4) Redis参数意义 文章目录Redis运维和开发学习笔记(4) Redis参数意义参数意义参数意义 Client连接 问题 id567800790 addr10.18.17.217:37310 fd1572 name age2039114 idle2034860 flagsN db0 sub0 psub0 multi-1 qbuf0 qbuf-free0 obl0 oll0 omem0 …

Effective C++学习第七天

条款23:宁以non-memeber、non-friend替换member函数non-member/non-friend可以给对象带来更大的封装性,从两个方面来考虑:1)考虑封装,越多东西被封装,它们就越不可见,就越少人看到它&#xff0c…

Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式

Redis运维和开发学习笔记(5) 主从复制和sentinel哨兵模式 主从复制 将主节点的数据改变同步给从节点 作用 备份数据读写分离 存在的问题: 手动干预切主等操作主节点的写能力受到单机限制主节点的存储能力受到单机限制 主从模式的故障恢复 当主节点发生故障时&am…

Effective C++学习第八天

条款26:尽可能延后变量定义式的出现时间当你定义了一个变量,如果在使用变量之前出现异常,那么你得承受一次构造成本和析构成本,而且你没有使用该变量;本条款给出的建议是延迟变量的定义,直到非得使用该变量…

Redis运维和开发学习笔记(6) 监控Redis工作状态-info命令

Redis运维和开发学习笔记(6) 监控Redis工作状态-info命令 文章目录Redis运维和开发学习笔记(6) 监控Redis工作状态-info命令info serverinfo clientinfo memoryinfo persistenceinfo statsinfo commandstatsinfo cpuinfo clusterinfo keyspaceinfo server Redis服务器相关的通用…

Effective C++学习第九天

条款32:确定你的public继承塑模出is-a模型class D(derived)以public形式继承class B(base),则每一个类型为D的对象同时也是一个类型为B的对象,反之不成立,因此B比D表现出更加一般化的…

Effective C++学习第十天

条款36:绝不重新定义继承而来的non-virtual函数non-virtual函数执行的是静态绑定,在编译器就已经决定,因此对象对用的函数只和指针的类型有关,而与指针所指的对象无关;记住non-virtual函数的性质:不变性凌驾…

Redis运维和开发学习笔记(7) 内存管理和过期策略

Redis运维和开发学习笔记(7) 内存管理和过期策略 文章目录Redis运维和开发学习笔记(7) 内存管理和过期策略内存回收策略惰性删除定时任务删除maxmemory过期策略allkeys-lru主从搭建测试搭建完毕主从测试结果volatile-lru测试结果volatile-ttl测试结果allkeys-lru内存回收策略 …

Effective C++学习第十一天

条款41:了解隐式接口和编译期多态面向对象编程世界总是以显式接口(源码可见的接口)和运行期多态(virtual)解决问题;对于templates及泛型编程的世界,隐式接口和编译期多态显得更加重要&#xff1…

Redis源码分析(零)学习路径笔记

文章目录第一阶段第二阶段 熟悉Redis的内存编码结构第三阶段 熟悉Redis数据类型的实现第四阶段 熟悉Redis数据库的实现第五阶段 熟悉客户端和服务器端的代码实现第六阶段 这一阶段主要是熟悉Redis多机部分的代码实现关于测试方面的文件有一些工具类的文件如下SORT命令的实现一些…

Effective C++学习第十二天

条款47:请使用traits classes表现类型信息STL有五类迭代器分类,input迭代器(只读,一次,向前)、output迭代器(可写,一次,向前)、forward迭代器(读/…

Redis源码分析(一)redis.c //redis-server.c

Redis源码分析(一)redis.c //redis-server.c 入口函数 int main() 4450 int main(int argc, char **argv) {4451 initServerConfig();4452 if (argc 2) {4453 ResetServerSaveParams();4454 loadServerConfig(argv[1]);4455 …

Linux 学习

1.linux文本命令行语言环境设置命令 查看当前语言环境: echo ¥LANG 修改: LANG选择的语言环境’ 引申:https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬链接和软连接 linux中文件的储存方式&#xf…

vivo C/C++工程师视频面试总结 20180802

1.自我介绍:有点儿紧张了,直接把自己简历上的一些信息信息说了一遍,说完之后在介绍了一下自己的平时的爱好和兴趣,感觉面试官没有理我,直接进入下一环节了。 2.项目详情:主要是自己最近的一个项目和自己负…

Redis源码分析(二)redis-cli.c

文章目录1. int main()2. parseOptions(int argc, char **argv) 进行ip和port的改变3. lookupCommand(char *name) 查找命令,判断命令合法3.2 strcasecmp(name,cmdTable[j].name)3.1 redisCommand cmdTable[]4. cliSendCommand(int argc, char **argv)4.1 cliConnec…

C语言中有bool变量吗?

1.C/C中定义的数据类型: C语言中定义了6种基本数据类型:short,int,long,float,double,char 4种构造类型:数组,结构体(struct),共用类型(union),枚举类型(enum) 指针类型和空类型 C语…

redis源码剖析(三)——基础数据结构

文章目录SDS链表字典这篇文章关于 Redis 的基础数据:SDS SDS (Simple Dynamic String)是 Redis 最基础的数据结构。直译过来就是”简单的动态字符串“。Redis 自己实现了一个动态的字符串,而不是直接使用了 C 语言中的字符串。 sds 的数据结…