Effective C++学习第二天

1:确保对象被使用前已先被初始化,读取未初始化的值会造成不明确的行为,可能导致程序终止运行或者其他不可预期的现象;在C++中,当你使用C part of C++(C++中C语言部分的内容)且初始化可能导致运行期成本,那么就不会保证一定初始化,而non-C part of C++,系统却能保证被初始化。对于内置类型(C++定义算术类型(整型和浮点型)和空类型为内置类型),需要手动完成初始化;对于自定义类型,需要用构造函数完成相应的初始化工作;

2:区分赋值(assignment)操作和初始化(initialization)的行为,在实现相同功能的情况下尽可能的使用初始化的方式

      对象成员的初始化动作发生在进入构造函数之前,进入构造函数本体之前,成员变量自动调用自己的default构造函数完成默认初始化(不使用初始化列表的情况下),然后进入函数体执行对应的功能;

      针对上述情况,使用成员初始化列表(member initialization list)替换常规的赋值操作可以省去一个赋值操作的过程,直接实现以各个成员变量的实参拷贝构造给形参,初始化列表中应包含所有的成员变量;

      对于大多数类型而言,比起先调用default构造函数后调用copy assignment操作符,只调用一次copy构造函数是比较高效的,但对于内置类型,其初始化和赋值的成本相同,但为了一致性效果,都采用初值化列表的形式;

      如果成员变量是const或者references,那么就一定需要初值,而不能被赋值

      初始化列表的初始化顺序是按照成员变量的定义顺序进行初始化的,与初始化列表中变量如何排列无关;

    结论:初始化时,使用初始化列表可以使你的程序更加高效;当我们想要用default构造成员变量的时候,我们也可以指定成员初始列,只要指定初始化实参为空就行;

3:当classes中有多个构造函数时,每个构造函数有自己的成员初始列,那么这样就可能出现重复的初值列,这种情况下可以将初始值列中那些“赋值表现像初始化一样好”的成员变量,改用它们的赋值操作,并把这些赋值操作合并成一个函数(通常是private)来供所有的构造函数使用;

4:static对象,其寿命从被构造出来到程序结束为止。通常函数内的static对象称为local static对象,其他的static对象称为non-local static对象;

      问题:当某个编译单元内的某个非non-local static对象的初始化动作使用了另一个单元内的的某个non-local static对象,可能所用到的这个对象可能没有初始化,而且C++对这个初始化的顺序没有明确的定义;

     解决方法:采用singleton设计模式,将每个non-local static对象搬到自己的专属函数内(该对象在函数内被声明为static),然后然后函数返回一个引用指向这个static对象,然后使用者调用这些函数,而不直接去指涉这些对象。这个方法的好处在于:C++保证了在函数内的local static对象会在“这个函数调用期间”“首次遇上该对象定义式时”被初始化;代码如下:

class filesystem

{

public:std:size_t numberdisks() const;

};

extern filesystem tfs;//修改为filesystem&  tfs(){staticfilesystem fs;return fs;}

class directory

{

public:directory(params) {std::size_t disks=tfs.numberdisks();//修改为  std::size_t disks=tfs().numberdisks;

};

directory tempdir(params);//修改为directory& tempdir() {static directory td; return td;}

      修改之后,程序用户完全和以前一样使用,唯一不同的就是使用函数返回的是指向static对象的引用,而非static对象本身;

      对于singleton模式下的reference-returning函数比较简单,往往可以变成inline函数,但是对于多线程环境下会带来很大的麻烦;

      引申:编译单元是指产生单一目标文件的那些源码,基本上它是单一源码文件加上其所包含的头文件,平常写程序的一个文档就称为一个编译单元;

      结论:为了避免在对象初始化之前使用对象,需要做三件事情:1)手工初始化内置类型non-number对象;2)使用成员初始值列表对方对象的所有成分;3)在初始化次序不确定的情况下可以考虑singleton设计模式,也就是在处理跨编译单元的初始化次序时,用local static对象替换non-local static对象。

5:如果自己没有声明类中的函数,编译器会自动生成一个default构造函数、一个copy构造函数、一个copy assignment操作符和一个析构函数(non-virtual),并且这些函数都是public和inline的;

     编译器生成的copy构造函数和copy assignment操作符只是单纯地将来源对象的每一个non-static成员变量拷贝给目标对象;

     如果自己声明了一个构造函数,则编译器不再提供default构造函数;

     编译器生成的copy assignment操作符,行为和copy构造函数一样,当且仅当生成的代码合法且有意义时;否则编译器拒绝为class生成operator=,如成员变量中含有引用或者const变量时,则编译器不能为自动生成一个copy assignment操作符;

     编译器拒绝自动生成一个copy assignment构造函数的情况:1)内含reference成员变量;2)内含const变量;3)在base classes将copy assignment操作符声明为private;编译器拒绝为derive classes生成一个copy assignment操作符;

6:如果想要阻止某些函数被创建出来,声明这个函数,并将其权限设置为private,但是member函数和friend函数还是可以调用private函数;

         阻值member或者friend函数调用的方法,利用一个base class,将需要阻止的函数(private权限)放到base class内,我们所需要做的就是(private)继承base class;当我们的类要生成copy构造函数和copy assignment函数时,会调用base class类中的对应函数,这些调用会被编译器拒绝,因为函数的权限是private;

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

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

相关文章

Redis运维和开发学习笔记(3)redis搭建集群

Redis运维和开发学习笔记(3)redis搭建集群 文章目录Redis运维和开发学习笔记(3)redis搭建集群Redis集群搭建Redis集群搭建 cp /etc/redis.d/redistest_7001.conf /etc/redis.d/redistest_XXXX.conf :%s/7001/xxxx/g 配置文件内容:cluster-enabled yes ############…

Effective C++学习第三天

1:为多态基类声明virtual析构函数当我们创建一个base class指针指向新生成的derived class时,当删除基类指针时,如果base class是一个non-virtual析构函数时,实际执行的结果通常是derived class中的base成分被销毁,der…

linux创建指定大小的文件

一、生成文件大小和实际占空间大小一样的文件 dd if/dev/zero ofname.file bs1M count1 文件名称name.file bs1M表示每一次读写1M数据,count50表示读写 50次,这样就指定了生成文件的大小为50M。 二、生成文件大小固定,但实际不占空间命令 …

Effective C++学习第四天

条款11:在operator中处理自我赋值的现象虽然我们在平时可能不会出现显示自我赋值的现象,当加入指针或者引用时,可能会出现不同的指针或引用指向同一对象(对象的不同别名),这时候我们就得考虑对象是否是同一…

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…