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

    0.1.守则01:把C++看做一个语言的集合,而不是单一的语言

        早期的C++只是叫"C with classes",但发展到今天已经成为一个多重泛型编程语言(Multi-paradigm programming language),它具有4种“子语言”:C 面向对象的C++ 模板C++ STL

    0.2.守则02:尽量使用const, enum, inline, 减少宏变量#define的使用
        ④对于#define的宏函数,尽量使用inline修饰的函数来代替#define
        #define 的使用确实用例出错,需要更费经历编写和改错误。编译出错后不能直接定位到出错位置。
        但下面应用却最好用#define
    #define PRINT_ERR(lpszFormat, ...)
    do
    {
    char szTmpBuf[Max_Log_Len + 1] = {0};
    snprintf(szTmpBuf, Max_Log_Len, lpszFormat, ##__VA_ARGS__);
    std::cerr << szTmpBuf<<std::endl;
    }while(0)

        因为这样用之后编译器可以帮你做snprintf参数的检查,这个可以避免很多代码错误。

    0.2.守则03: 尽可能使用const关键字
        我的理解是提前规划好变量或者函数用途,是作为参照还是要进行记录。尽可能限制到最小权限,降低错误风险。
        迭代器的const const_iterator
       ⑥在定义类的常量与非常量成员函数时,避免代码重复 二者可以复用一套代码。

    0.3.守则07: 在多态的基类中,把析构函数声明为虚函数
        某些类不是被用来当做基类的,比如std::string和STL,否则可能继承后导致析构函数不被调用,引发子类中的内存泄漏。

    0.4.守则09: 不要在构造函数和析构函数中调用虚函数
        在C++中,当子类开始构造时,它所包含的父类的部分要先完成构造,所以率先调用的构造函数是它的父类"Transaction"的构造函数。现在问题来了,因为父类的构造函数调用了一个纯虚函数,这就会导致即使你创建的是它的子类对象,这个虚函数也不会绑定到子类的版本上,而是使用的父类版本。

    0.5.守则10: 赋值操作符要返回一个指向*this的引用
          守则11: 赋值操作符要处理自赋值

    0.6.什么是RAII?
        RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。

    0.7.守则19: 把类的设计看作类型的设计

    0.8.守则20: 多用常量引用传递,少用值传递.
        C++编译器会把引用作为指针来实现,所以引用传递本质上其实就是指针传递。因此,对于例如int的原始类型,直接用值传递还是比引用传递要高效,对于STL的迭代器和STL函数对象(function object / functor),即提供至少一个operator()的实现的某类对象,值传递同样也比引用传递高效。
        多用常量引用传递,少用值传递。引用传递通常更高效,也能避免对象切割问题。
        但是作为惯例,对于原始类型,STL迭代器,STL函数对象,值传递还是更加高效,这是仅有的例外。

    1.不要对数组使用多态

        数组空间连续,靠偏移访问,多态转换后因为其类型变化,类型所占空间变化。此时偏移访问的方式便不能正确去得数组各元素准确其实位置。

    2.创建模板时,应避免无用的缺省构造函数。

        通过仔细设计模板可以杜绝对缺省构造函数的需求。例如标准的vector模板(生成一个类似于可扩展数组的类)对它的类型参数没有必须有缺省构造函数的要求。很多模板类没有以仔细的态度去设计,没有缺省构造函数的类就不能与许多模板兼容。

        无用缺省构造函数会在没有足够的数据时初始化一个对象,而此时该对象中许多属性处于无效状态。倘若我们不判断这些无效状态,则代码很有可能运行不正常;倘若判断无效状态,则会影响运行的效率,这种对象的使用者也要为此付出更多时间和代码。
        而使用没有缺省构造函数的类的确有一些限制,但它给你提供了一种保证:这个类被正确地建立和高效地实现。

        避免方法是直接分配空间,而后在该空间以如下方式调用拷贝构造函数和析构函数。这样子只提出了要求模板参数类有拷贝构造即可
        ::new(__p) _Tp(__val)
        __p->~_Tp()

    3.智能指针

    template<class T>                    // 模板类,指向T的
    class SmartPtr {                     // 灵巧指针
    public:
      SmartPtr(T* realPtr = 0);
      T* operator->() const;
      T& operator*() const;
      template<class newType>             // 模板成员函数
      operator SmartPtr<newType>()        // 为了实现隐式类型转换. 执行类似:
      {
        return SmartPtr<newType>(pointee);
      }
      ...
    };

    实现模板类的不同类型实例间的隐式转换。需要用到成员函数模板,即成员函数拥有一个未知类型模板参数。
    SmartPtr<childclass> c;
    SmartPtr<parentclass> p = c;

  • 相关阅读:
    hibernate_0100_HelloWorld
    MYSQL子查询的五种形式
    JSF是什么?它与Struts是什么关系?
    nop指令的作用
    htmlparser实现从网页上抓取数据(收集)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the
    FCKeditor 在JSP上的完全安装
    Java遍历文件夹的2种方法
    充电电池和充电时间说明
    吃知了有什么好处
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/3231583.html
Copyright © 2011-2022 走看看