Effective c++

作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/86941?type=1&order=0&pos=4&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/86302?type=1&order=0&pos=32&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/86302?type=1&order=0&pos=32&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网
 

1.条款一:视c++为一个语言联邦。

             总共分为四个层次,<1>:c++是以c为基础的,预处理器等都来自c.<2>object-Oriented C++   封装继承多态等。<3>模板编程。<4>STL.。对容器、迭代器、算法、以及函数对象有一些规定。

2.条款二:尽量以const,enum,inline替换#define

              换句话说就是用编译器替换预处理器比较好。用const等可以有参数类型检查。此外,宏是由预处理器处理的,也许不会进入记号表,当有一个宏被定义在非你所写的头文件内,很难定位。有两种特殊情况,第一是定义常量指针,不仅指针是常量,指针指向的也是常量,所以const要写两次

              第二则是类专属常量,必须将他定义为static.宏函数的一个缺点是有可能里面的变量自增两次,当含自增的话。

3.条款三,尽可能使用const,只要是个常量。将const实施于成员函数的目的,是为了确认该成员函数可作用于const对象身上,第二,使操作const对象成为可能,改善c++程序效率的一个根本办法是传常量引用。

4.条款四:确定对象被使用前都已经被初始化。

                 为内置型对象进行手工初始化。构造函数最好使用成员初值列作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网
 

1.条款一:视c++为一个语言联邦。

             总共分为四个层次,<1>:c++是以c为基础的,预处理器等都来自c.<2>object-Oriented C++   封装继承多态等。<3>模板编程。<4>STL.。对容器、迭代器、算法、以及函数对象有一些规定。

2.条款二:尽量以const,enum,inline替换#define

              换句话说就是用编译器替换预处理器比较好。用const等可以有参数类型检查。此外,宏是由预处理器处理的,也许不会进入记号表,当有一个宏被定义在非你所写的头文件内,很难定位。有两种特殊情况,第一是定义常量指针,不仅指针是常量,指针指向的也是常量,所以const要写两次

              第二则是类专属常量,必须将他定义为static.宏函数的一个缺点是有可能里面的变量自增两次,当含自增的话。

3.条款三,尽可能使用const,只要是个常量。将const实施于成员函数的目的,是为了确认该成员函数可作用于const对象身上,第二,使操作const对象成为可能,改善c++程序效率的一个根本办法是传常量引用。

4.条款四:确定对象被使用前都已经被初始化。

                 为内置型对象进行手工初始化。构造函数最好使用成员初值列作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网
 

1.条款一:视c++为一个语言联邦。

             总共分为四个层次,<1>:c++是以c为基础的,预处理器等都来自c.<2>object-Oriented C++   封装继承多态等。<3>模板编程。<4>STL.。对容器、迭代器、算法、以及函数对象有一些规定。

2.条款二:尽量以const,enum,inline替换#define

              换句话说就是用编译器替换预处理器比较好。用const等可以有参数类型检查。此外,宏是由预处理器处理的,也许不会进入记号表,当有一个宏被定义在非你所写的头文件内,很难定位。有两种特殊情况,第一是定义常量指针,不仅指针是常量,指针指向的也是常量,所以const要写两次

              第二则是类专属常量,必须将他定义为static.宏函数的一个缺点是有可能里面的变量自增两次,当含自增的话。

3.条款三,尽可能使用const,只要是个常量。将const实施于成员函数的目的,是为了确认该成员函数可作用于const对象身上,第二,使操作const对象成为可能,改善c++程序效率的一个根本办法是传常量引用。

4.条款四:确定对象被使用前都已经被初始化。

                 为内置型对象进行手工初始化。构造函数最好使用成员初值列

作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/85204?type=1&order=0&pos=154&page=0
来源:牛客网

c++是一门面向对象的语言,这就意味着我们必须亲手构造一些类,而每一个类都会有构造函数、析构函数、赋值函数等。

 条款5:了解c++默默编写并调用了那些函数。

             什么时候空类不再是空类呢,当编译器开始处理的时候,编译器会为空类创建一些默认构造函数以及拷贝构造函数还有赋值操作以及析构函数。

            注意: 编译器产生的析构函数不是一个虚函数。

条款6:若不想使用编译器自动生成的函数,就该明确拒绝。

         方法是可将相应的成员函数声明为private,并且不予以实现。

条款7;为多态基类声明vitual析构函数

            欲实现虚函数,对象必须携带某些信息,主要用来在运行期决定哪一个虚函数盖被调用。很多人的心得是:不要无端将类的所有析构函数声明为虚函数,只有类中含有一个虚函数时,才将析构函数声明为虚函数。但还是会出错,当两个类是否含有虚函数时,被继承下去的子类,当两种基类指针指向同一个·子类时,删除不带虚函数的基类指针,就存在内存泄漏、。

           必须为纯虚函数提供定义。

           如果是为实现多态的基类,就必须声明虚析构函数,如果不是作为基类使用,就不要声明虚析构函数。

条款8:别让异常逃离析构函数。假如析构函数必须执行一个动作,而该动作在失败时抛出异常该怎办。一个解决办法是创建一个资源管理的类,在析构函数中调用close。

            析构函数绝对不要吐出异常

            如果客户需要在运行期间抛出的异常做出反应,那么class应该提供一个普通函数执行该操作。

条款9:绝不在构造和析构过程中调用虚函数。

             在基类构造期间,虚函数不是虚函数。

条款10:令operator=返回一个对对象的引用

          主要是为了实现连锁赋值

条款11:在operator=中处理“自我赋值”。

            可以利用copy及swap技术,先生成一个副本,再交换,返回对象引用。

条款12:复制对象时勿忘其每一个部分。

            Copying 函数应该确保复制对象内的所有成员变量及所有基类成分。

            不要尝试以某个Copying函数实现另一个Copying函数,应该将共同机能放在第三个函数中,并由两个Copying函数共同调用。

作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/86302?type=1&order=0&pos=32&page=0
来源:牛客网

这一章的主要内容是围绕资源管理。

        不论哪一种资源,重要的是,当你不再使用时,必须将它还给系统。

条款13:以对象管理资源

        将资源放进对象内,当控制流离开时,该对象的析构函数会自动释放那些资源。

        获得资源后立刻放进管理对象

        管理对象运用析构函数确保资源被释放。

        标准库里提供的智能指针正是针对这种形势而设计的特制产品。其析构函数自动对其对象调用delete.

         由于智能指针被销毁时会自动删除它所指之物,所以一定要注意别让多个智能指针指向同一个对象。如果真是那样,对象会被删除一次以上,而那样会使你的程序搭上驶向“未定义行为”的列车上。为了预防这个问题,智能指针有一个不寻常的性质:若通过拷贝构造函数或拷贝操作符复制他们,他们会变成空,而复制的指针将取得资源的唯一拥有权。

       但智能指针并非管理动态分配资源的神兵利器。举个例子,STL容器要求其元素发挥正常的复制行为,因此这些容器容不下智能指针。

         智能指针的替代方案是“引用计数型智慧指针”,持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。但引用技术型智慧指针无法打破环状使用。例如两个其实已经没被使用的对象彼此互指。

         两种指针都在其析构函数内做delete操作,而不是做delete[]操作,当为数组动态分配一块内存空间时,发生内存泄漏。可叹的是,这种操作在编译器中是可以通过的。但是,vector和string几乎总是可以取代动态分配而得到的数组。

        作为最后批注,我必须指出,工厂函数返回的“未加工指针”简直是对资源泄露的一个死亡邀约,因为调用者极易在这个指针身上忘记调用delete.首先必须记得将工厂函数的返回值存储于智能指针对象内。

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

        并非所有资源都是基于堆的,对那种资源而言,智能指针和引用计数型指针往往不适合作为资源掌管者,这时候需要构建自己的资源管理类。

        禁止复制

        对底层资源祭出“引用计数法”

            辛运的是引用计数指针允许指定所谓的删除器,那是一个函数或函数对象,当引用次数为0时便被调用,删除器对tr1::shared_ptr构造函数而言是可有可无的第二参数。

        复制底部资源

        只要你喜欢,可以针对一份资源拥有任意数量的复件,而你需要“资源管理类”的唯一理由是,当你不再需要某个复件时确保它被释放。在此情况下复制资源管理对象,应该同时也复制其包裹的资源。,这时,进行的是深度拷贝。

         转移底部资源的拥有权

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

        如果你希望有一个函数来处理原始指针对象,就必须将智能指针或引用计数型指针转换为原始指针。这两种指针都提供一个get成员函数,用来执行显式转换。

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

条款17:以独立语句将newed置入智能指针

               因为编译器在同一行语句内有重新排列的自由,在开辟内存和放入资源管理类对象之间,调用另一个函数时可能会发生意外,此时就有资源泄露的风险。这一条是与第15条有关。开辟内存后先直接放入引用计数指针,在进行类型转换,再进行其   他操作。

             std::str1::shared_ptr<widget> pw(new Widget);

              processWidget(pw,priority());

作者:帅气的小小全
链接:https://www.nowcoder.com/discuss/88796
来源:牛客网
 

设计与声明

条款18:让借口容易被正确使用,不易被误用

            明智而审慎地导入新类型对预防接口被误用有神奇疗效。一旦正确的类型就定位,限制其值有时候是通情达理。例如一年只有12月份,所以month应该反映这一事实。办法之一是   利用enum表现月份,但enums不具备我们希望拥有的类型安全性,例如enums可被拿来当一个ints使用。比较安 全的解法是预先定义所有有效的month,再定义一个私有构造函数,阻止其他非法的月份。

            预防另一办法是限制类型内什么事可做,什么事不能做。常见的限制是加上const;尽量令你的types与内置的类型也一致。为避免资源泄露,factory函数直接返回一个智能指针。

条款19:设计class犹如设计type

                新type对象如何创建和销毁?

                对象的初始化和赋值有什么区别?

                新type的对象如果被传值,意味着什么?

                什么是新type的合法值?

                你的新type需要配合某个继承图系吗?

条款20:宁以常量引用替换传值。

                如果有个内置类型,传值往往比传引用效率高一些

条款21;必须返回对象时,别妄想返回其引用。

             绝不要返回指针或引用指向一个本地栈对象。

条款22:将成员变量声明为private

t条款23:宁以非成员、非友元替换成员函数。

条款24:若所有参数皆需类型转换,请为此采用非成员函数。

条款25:考虑写出一个不抛出异常的swap函数。

            如果swap的缺省实现在可接受的效率,就不必改变。

            1.提供一个public swap成员函数,让他高效的置换类型。绝不该抛出异常。

            2.在自己的class所在的命名空间内提供一个非成员swap函数,让他调用上述函数。

            3.为自己的类特化std::swap.并令它调用自己的swap成员函数。

            最后,如果你调用swap,请确定包含一个using 声明式,以便让std::swap在自己的函数内曝光,然后不加任何namespace修饰符,赤裸裸的调用swap.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值