Effective C++学习第五天

条款14:在资源管理类中小心copy行为

          当我们深入理解“资源取得时机是初始化时机(RAII)”概念,并以此作为“资源管理类”的核心时,我们可能会遇到将RAII对象复制的情况,一般有两种情况处理这个现象:1)如果我们的RAII对象是唯一的,那么复制就不合理,因此我们应该禁止copy构造的行为,正确的处理方式:将copy函数定义为private(base class),并用derived class private继承这个函数来阻止copy行为;  2)使用引用计数法,即智能指针的形式来实现对所有拷贝资源的追踪,但是智能指针的缺省行为是当引用次数为0时删除其所指向的对象。如果我们要实现的功能不是释放资源,这时候就应该自定义智能指针的deleter(一个函数或者函数对象),当引用次数为0时调用这个函数实现相应功能,如:

class lock{

public:

         explicit lock(mutex *pm) : mutexptr(pm,unlock) { }  //用mutex初始化shared_ptr,并以unlock函数为删除器

private:

                 std::tr1::shared_ptr<mutex>mutexptr;

};

另外,上述例子中不需要声明析构函数,因为class 析构函数会自动调用其non-static成员变量的析构函数;3)复制底部资源,采用深度拷贝的方法;4)采用转移底部资源拥有权的方法,也就是所谓的auto_ptr指针;

条款15:在资源管理类中提供对原始资源的访问

          当你需要访问一个RAII class对象的内部原始资源时,有两种方法可以达成目标:1)在类的内部提供一个get成员函数,用来执行显示转换,也就是返回类内部指针的原始复件;2)允许隐式转换到底部原始指针;在智能指针中,重载了指针取值操作符(operator->和operator*)来实现隐式转换;对于一般的来说,可以在类中提供一个隐式转换函数;如:

class font{

public:                                                                        //显示转换函数:

            explicit font(fonthandle fh) : f(fh){ }                fonthandle get() const {   return f;  }

            ~font() { releasefont(f); }                            //隐式转换函数  

private:                                                           operator fonthandle() const {return f;}//没太明白怎么隐式转换的

          fonthandle f;                                                                                                      //operator起到什么作用?

}

//显示转换                                                                   //隐式转换

void changefontsize(fonthandle f,int newsize);          void changefontsize(fonthandle f,int newsize);

font f(getfont());                                                       font f(getfont());

changefontsize ( f.get(), newfontsize);                      changefontsize ( f, newfontsize);

//但隐式转换会出一个问题

font f1(getfont());    

fonthandle f2=f1;   //原意是拷贝,结果是f1先转化为底部的fonthandle,然后拷贝,一旦此时f1被销毁,f2就处于指向资源被释放的状态(dangle)

条款16:成对使用new和delete时采取相同的方式

               如果你在new的表达式中使用[ ],则必须在相应的delete表达式中也使用[ ],如果没有使用[ ],那么也一定不要在delete中使用[ ];

条款17:以单独语句将newed对象置入智能指针中

          对于以下代码分析;

            int priority( );

           void processwidget(std :: tr1 :: shared_ptr<wideget>pw,int priority);

            //调用时   processwidget(new widget, priority( ));//编译错误,shared_ptr构造函数是explicit类型,不允许隐式转换

           //processwidget(std :: tr1 :: shared_ptr<wideget>(new widget),priority( ) );

           这个函数在调用processwidget之前,编译器必须创建代码,完成以下三件事情:1)调用priority;2)执行new widget;3)调用 std::tr1::shared_ptr构造函数;但是1)和2)的执行顺序和编译器有关,如果先执行2)后执行1),且在执行1)的时候发生异常,那么new widget返回的指针就会失效,那么内存泄露就产生了;

          解决上述问题的方法:使用分离语句,把创建对象和给智能指针赋初值的语句分离出来,原因是:编译器对于“跨越语句的各项操作”没有重新排列的自由(只有在语句内才拥有那个自由度);代码如下:

         std::tr1::shared_ptr<widget>pw(new widget);

          processwidget(pw,priority( ));

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

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

相关文章

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

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

Effective C++学习第六天

条款18&#xff1a;让接口更容易被正确使用&#xff0c;不易被误用设计接口的原则&#xff1a;正确性、高效性、封装性、维护性、延展性以及协议的一致性&#xff1b;设计原则&#xff1a;1&#xff09;导入新类型来预防很多客户端的错误&#xff0c;多使用系统类型&#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&#xff1a;宁以non-memeber、non-friend替换member函数non-member/non-friend可以给对象带来更大的封装性&#xff0c;从两个方面来考虑&#xff1a;1&#xff09;考虑封装&#xff0c;越多东西被封装&#xff0c;它们就越不可见&#xff0c;就越少人看到它&#xff0c…

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

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

Effective C++学习第八天

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

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&#xff1a;确定你的public继承塑模出is-a模型class D&#xff08;derived&#xff09;以public形式继承class B&#xff08;base&#xff09;&#xff0c;则每一个类型为D的对象同时也是一个类型为B的对象&#xff0c;反之不成立&#xff0c;因此B比D表现出更加一般化的…

Effective C++学习第十天

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

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

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

Effective C++学习第十一天

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

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

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

Effective C++学习第十二天

条款47&#xff1a;请使用traits classes表现类型信息STL有五类迭代器分类&#xff0c;input迭代器&#xff08;只读&#xff0c;一次&#xff0c;向前&#xff09;、output迭代器&#xff08;可写&#xff0c;一次&#xff0c;向前&#xff09;、forward迭代器&#xff08;读/…

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

Redis源码分析&#xff08;一&#xff09;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文本命令行语言环境设置命令 查看当前语言环境&#xff1a; echo &#xffe5;LANG 修改&#xff1a; LANG选择的语言环境’ 引申&#xff1a;https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬链接和软连接 linux中文件的储存方式&#xf…

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

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

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

文章目录1. int main()2. parseOptions(int argc, char **argv) 进行ip和port的改变3. lookupCommand(char *name) 查找命令&#xff0c;判断命令合法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中定义的数据类型&#xff1a; C语言中定义了6种基本数据类型&#xff1a;short,int,long,float,double,char 4种构造类型&#xff1a;数组&#xff0c;结构体&#xff08;struct&#xff09;&#xff0c;共用类型(union)&#xff0c;枚举类型(enum) 指针类型和空类型 C语…

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

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

C++迭代器使用错误总结

指针和迭代器的区别&#xff1a; 迭代器&#xff1a; &#xff08;1&#xff09;迭代器不是指针&#xff0c;是类模板&#xff0c;表现的像指针。他只是模拟了指针的一些功能&#xff0c;通过重载了指针的一些操作符&#xff0c;->,*, --等封装了指针&#xff0c;是一…