传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 倾心莫若初见 于 2016-12-27 10:44 编辑

承接【笔记】C++程序员必知十大条款(上)此篇文章


    条款06:若不想使用编译器自动生成的函数,就该明确拒绝
    通常如果你不希望类支持某一特定技能,只要不说明对应函数就是了。但这个策略对拷贝构造函数和拷贝赋值操作符却不起作用。因为编译器会“自作多情”的声明它们,并在需要的时候调用它们。
     由于编译器产生的函数都是public类型,因此可以将拷贝构造函数或拷贝赋值操作符声明为private。通过这个小“伎俩”可以阻止人们在外部调用它,但是类中的成员函数和友元函数还是可以调用private函数。解决方法可能是在一个专门为了阻止拷贝动作而设计的基类。(Boost提供的那个类名为noncopyable)。
     请记住:

为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为private并且不予实现。使用像noncopyable这样的基类也是一种做法。   
    条款07:为多态基类声明virtual析构函数
    当基类的指针指向派生类的对象的时候,当我们使用完,对其调用delete的时候,其结果将是未有定义——基类成分通常会被销毁,而派生类的充分可能还留在堆里。这可是形成资源泄漏、败坏之数据结构、在调试器上消费许多时间。
    消除以上问题的做法很简单:给基类一个virtual析构函数。此后删除派生类对象就会如你想要的那般。
     任何类只要带有virtual函数都几乎确定应该也有一个virtual析构函数。
     如果一个类不含virtual函数,通常表示它并不意图被用做一个基类,当类不企图被当做基类的时候,令其析构函数为virtual往往是个馊主意。因为实现virtual函数,需要额外的开销(指向虚函数表的指针vptr)。
     STL容器都不带virtual析构函数,所以最好别派生它们。
     请记住:

带有多态性质的基类应该声明一个virtual析构函数。如果一个类带有任何virtual函数,它就应该拥有一个virtual析构函数。
一个类的设计目的不是作为基类使用,或不是为了具备多态性,就不该声明virtual析构函数。   
    条款08:别让异常逃离析构函数
    C++并不禁止析构函数吐出异常,但它不鼓励你这样做。C++不喜欢析构函数吐出异常。
     如果可能导致异常:

如果抛出异常,就结束程序。(强迫结束程序是个合理选项,毕竟它可以阻止异常从析构函数传播出去。)
捕获异常,但什么也不做。   
     如果某个操作可能在失败时抛出异常,而又存在某种需要必须处理该异常,那么这个异常必须来自析构函数以外的某个函数。
     请记住:

析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序。
如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么类应该提供一个普通函数(而非在析构函数中)执行该操作。   
    条款09:决不让构造和析构过程中调用virtual函数
    你不该在构造函数和析构函数中调用virtual函数,因为这样的调用不会带来你预想的结果。
    因为:基类的构造函数的执行要早于派生类的构造函数,当基类的构造函数执行时,派生类的成员变量尚未初始化。派生类的成员变量没初始化,即为指向虚函数表的指针vptr没被初始化又怎么去调用派生类的virtual函数呢?析构函数也相同,派生类先于基类被析构,又如何去找派生类相应的虚函数?
    唯一好的做法是:确定你的构造函数和析构函数都没有调用虚函数,而它们调用的所有函数也不应该调用虚函数。
    解决的方法可能是:既然你无法使用虚函数从基类向下调用,那么我们可以使派生类将必要的构造信息向上传递至基类构造函数。即在派生类的构造函数的成员初始化列表中显示调用相应基类构造函数,并传入所需传递信息。
    请记住:

在构造和析构函数期间不要调用虚函数,因为这类调用从不下降至派生类。   
    条款10:令operator= 返回一个reference to *this
    对于赋值操作符,我们常常要达到这种类似效果,即连续赋值:
      int x, y, z;
      x = y = z = 15;
      为了实现“连锁赋值”,赋值操作符必须返回一个“引用”指向操作符的左侧实参。
      即:
        Widget & operator = (const Widget &rhs)
        {
            ...
            return *this;
        }
      所有内置类型和标准程序库提供的类型如string,vector,complex或即将提供的类型共同遵守。
      请记住:

令赋值操作符返回一个reference     to *this。     



精华推荐:

3分钟带你读懂C/C++学习路线
为什么来黑马程序员学C/C++? 稳做IT贵族人才!
2016最新C++学习路线图(附完整视频资源)+ 笔记 + 工具 + 面试题总结!
分享至 : QQ空间
收藏

1 个回复

倒序浏览
c++感觉很高大上,可惜我是学java的
来自宇宙超级黑马专属苹果客户端来自宇宙超级黑马专属苹果客户端
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马
关闭

站长推荐 上一条 /4 下一条