zoukankan      html  css  js  c++  java
  • Effect C++

    Effective C++ 已经看过若干编了,里面基本都是的是C++使用最基本的准则,许多条目已经被奉为标准。最近翻看,将一些有感觉的知识点简要记录一下。

    条目7:为多态基类声明virtual析构函数

         一个类如果将会以多态的方式使用,那么就要提供一个virtual dtor。这样才能保证相关的对象被正确销毁。但粗暴地为所有的类提供虚析构函数也是错误的,这样导致效率的低下,甚至是“可移植性”问题(虚函数的实现细节是由编译器决定的,一个类是否包含虚函数会影响类实例的内存布局)。因此在设计一个类的时候,要考虑它是否可能会被继承。一个经验是”只有类包含一个虚函数的时候,才将它的析构函数也声明为虚的“。

        反过来,如果一个类的析构函数是非虚的(或是根本没有声明),那么这通常意味这着这个类并不设计为一个基类。但实际上真正危险的地方是”多态的方式使用“,继承并不意味着多态,所以如果你确定并不会以多态的方式使用某个类继承体系,那么基类没有虚析构函数也没有关系。不过我觉得还是尽量避免的好。

    条款9:不要在构造函数或析构函数中调用虚函数

        有时我们希望基类的构造函数能够区分是一个基类对象正在构造,还是一个派生类对象正在被构造,并以此来执行不同的代码。我们因此可能会在基类中声明一个虚函数来封装这些代码,然后在构造函数中调用该虚函数。

        但实际上C++并不支持我们这么做,如果在基类的构造函数中调用虚函数,调用到的总是基类的虚函数实现。这是因为此时子类的成员尚未被初始化,调用子类的函数极可能导致未定义的行为。因此C++杜绝了这种可能性。其实在基类的构造函数中,如果查询该当前对象的动态类型,得到的也必然是基类类型。

       对析构函数同样如此。 我们不仅要注意直接调用虚函数,而且要注意间接调用。

       如果我们确实需要第一段所述功能,那么可以考虑给基类构造函数添加一个参数,派生类的初始化类表中通过提供参数来订制不同的行为。如果这仍然不能满足需求,那就考虑更改一下设计了。

    条款13~15 通过对象管理资源

        通过对象来管理资源可以获得很多好处,充分利用C++对对象的支持: 构造,生存期,析构来保证资源使用的安全性。你可以通过auto_ptr这样简单的对象来管理单个的堆对象资源,或许你需要抽象一个来来封装资源。这样的类就是资源管理类,具有单一的功能:持有资源。将资源的管理和使用分开可以使代码具有更好的风格和异常安全性。

       我们一般遵循RAII,resouce acquire in initialization 的原则,即在资源管理类的初始化构造中获取资源,在析构中销毁资源。

       资源管理类的COPY行为需要特别注意,你可能不允许拷贝,或是引用记数的COPY。

       某些API可能需要原始资源指针,你可以提供隐式的类型转换,或是显示的get函数来提供原始类型。但后者更安全。

    条款23: 以non-member non-friend函数代替member函数

        如果一个成员函数不需要直接访问类的私有成员,那么考虑用一个non-member non-friend的方法来代替它。这个问题考虑的是封装性。封装性意味着越少的代码能够访问类的私有成员,那么说明封装性越好。这点与面相对象的“将数据与操作数据的方法绑定在一起”的设计思想看起来相悖,但其实这个准则本身就是对面向对象的一个误解。

       提供一个none-member none-friend的函数能够提升我们的封装性。一般的做法是提供一个名字空间或是一个只包含静态方法的类**Utility,将这样的一些功能性方法组织在一起。这个条框与上一个用类来管理资源的思想其实有异曲同工之妙,其根本思想就是“单一功能原则”。 这个类提供基本的功能,至于将一些功能组合成一个方法以方便用户,就通过另一个类**utility来做吧。

       在库的设计中,比如C++标准库,这种设计很常见。可以将不同的功能性方法组织到不同的头文件、名字空间,以减少编译依赖。

       但在应用程序的设计中,我们偶尔需要一两个这样的方法,我认为直接用memeber函数就好了。

    条款30:inline函数

        如果没有证据表明某个函数被大量调用导致了效率问题,就不要使用inline。 inline总是伴随着一些风险的。 像构造函数和析构函数如果声明为inline几乎不会是正确的,因为编译器在构造函数和析构函数中可能插入了一些你所不知的代码。

  • 相关阅读:
    三层架构之解耦
    自动升级 组件
    C语言常量与指针
    ASP.NET MVC Model元数据
    Web层后端权限模块
    java中文排序问题(转)
    JDWP
    bat执行java程序的脚本解析
    jdom dom4j解析xml不对dtd doctype进行验证(转)
    Dom4j SAXReader Constructors
  • 原文地址:https://www.cnblogs.com/longhuihu/p/10423431.html
Copyright © 2011-2022 走看看