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;

  • 相关阅读:
    SQL 中单引号 和一些特殊字符的处理
    jquery 删除table行,该如何解决
    jQuery获取Select选中的Text和Value,根据Value值动态添加属性等
    C#中DataTable
    jquery操作select(取值,设置选中)
    JS刷新页面总和!多种JS刷新页面代码!
    VS中代码对齐等快捷键
    SQL递归查询(with cte as)
    SQL Server 公用表表达式(CTE)实现递归的方法
    linux ls和 ll 命令
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/3231583.html
Copyright © 2011-2022 走看看