zoukankan      html  css  js  c++  java
  • Effective C++ 笔记

    自己习惯C++

    1、C++为一个语言联邦

    STL,Template,智能指针,C++11

    2、尽量以const,enum,inline替换#define

    1)预处理在符号表中不存在,出现bug不好定位;目标码中也不会有多份Pia

    eg:

    #define Pia 3.14 (instead of--->) const double Pia = 3.14

    2)inline代替#define函数

    eg:

    #define MAX(a,b) f(

             if((a) > (b))

                       return (a)

             else

                       return (b)

             )

    template<class T>

    inline T Max(const T& a, const T& b)

    {...}

    3、尽量使用const

    1)区别不多说(const出现在星号左边,表示被指物是常量;出现在右边,表示指针本身是常量;出现在两边,被指物和指针都是常量)

    char str[] = "hello";

    char* p = str;

    const char* p = str;

    char* const p = str;

    const char* const p = str;

    2)const std::vector<int>::iterator iter = vec.begin();//like T* const;指针不能变,被指物可以变

    *iter = 10;//right

    iter++;//error

    遍历的时候,不能这样声明,可以使用下面这种

    如果想声明被指物不可变,使用const_iterator

    std::vector<int>::const_iterator citer = vec.begin();

    *citer = 10;//error

    citer++;//right

    3)函数参数const,不让内部改变参数属性;

    返回值const,一些可能的bug可以避免,如(a*b)=c的错误

    4)const成员函数:允许const属性的重载

    4、确认对象被使用前已经被初始化

    构造,析构,赋值

    5、了解C++默默编写并调用哪些函数

    构造函数(T()),析构(~T()),拷贝构造(T(const T& rhs)),复制函数(T &operator=(const T& rhs))

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

    拷贝构造,复制函数声明为private且不定义

    7、为多态基类声明virtual析构函数

    防止资源泄漏(保证子类析构函数被调用)

    8、别让异常逃离析构函数

    异常时终止或者吞下

    将可能抛出异常的代码提供给用户管理

    9、绝不在构造和析构过程中调用virtual函数

    构造和析构期间不要调用virtual函数,因为这类调用不会下降到子类的虚函数

    原因:

    子类构造前,先构造父类;父类调用虚函数,只能调用父类自己的函数,因为子类还没有构造;

    同理,子类析构,先析构自己,然后析构父类,当父类析构函数调用虚函数,不可能指向子类的虚函数,因为子类已经析构不存在了。

    PS:

    一个virtual函数,就有一个虚表;虚表是在编译期创建的。

    在执行期,根据虚表,程序找到虚函数实现体,实现多态

    10、令operator= 返回一个reference to *this

    eg:

    template <class T>

    T& operator=(const T& rhs)

    {

             ...

             return *this;

    }

    11、在operator=中处理“自我赋值”

    eg1:

    template <class T>

    T& operator=(const T& rhs)

    {

             if(this == &rhs)return *this;

             ...

             return *this;

    }

    eg2:

    copy-and-swap技术

    template <class T>

    T& operator=(const T& rhs)

    {

             if(this == &rhs)return *this;

             //copy-and-swap

             bitmap* pOrig = pb;

             pb = new bitmap(*rhs.pb);

             delete pOrig;

             //

             return *this;

    }

    12、复制对象时勿忘期每一个成分

    如果是子类赋值函数或者是复制构造函数,除了复制子类所有成员变量;

    需要适当调用父类的对应函数,父类不满足;父类也需要重新这些函数

    eg见代码effective12

    资源管理

    13、以对象管理资源

    构造函数获得资源,析构函数释放资源;

    使用智能指针封装:tr1::shared_ptr和auto_ptr。

    关于智能指针,见另外一片blog

    14、在资源管理类中小心copying行为

    15、在资源管理类中提够对原始资源的访问

    原始资源获取;

    显式转换安全

    隐式转换——对客户方便,不安全

    16、成对使用new和delete时采用相同形式

    new, delete

    new [], delete []

    17、以独立语句将newed对象置入智能指针

    eg:

    std::tr1::shared_ptr<T> pw(new T);

    processT(pw,test())

    代替

    processT(std::tr1::shared_ptr<T>(new T),test())

    防止test()出现异常,new T之后没有调用tr1::shared_ptr出现资源泄漏

    设计与声明

    18、让接口容易被正确使用,不易被误用

    类型一致性;

    shared_ptr防范跨DLL错误。

    19、设计class犹如设计type

    20、宁以pass-by-refenrence-to-const替换pass-by-value

    1)引用传递代替值传递(这个在Java,python中都已经默认使用。当然简单内置的类型还是value传递,其他都是引用传递了)

    2)高效,没有拷贝构造函数,析构函数执行

    3)STL使用pass-by-value比较适合,估计也是其中成员,而不是STL容器本身

    21、必须返回对象时,别妄想返回其reference

    1)绝对不要返回pointer或reference指向一个local stack对象,或者返回一个reference指向一个heap-allocated对象,

    或者返回pointer或reference指向一个local static 对象

    2)栈、堆、静态对象都不要作为引用返回

    22、将成员变量声明为private

    set***函数便于更改private变量,不易疏漏

    23、宁以non-member、non-friend替代member函数

    24、若所有参数且需类型转换,请为此采用non-member函数

    operator*(+,-等等)有隐式转换的左值,只能是全局函数,不能是成员函数

    25、考虑写一个不抛异常的swap函数

    实现

    26、尽可能延后变量定义式的出现时间

    不要提前定义,使用前定义

    27、尽量少做转型动作

    const_cast<T>:常量转换

    dynamic_cast<T>:继承关系转换

    reinterpret_cast<T>:eg point to int 转型为 int

    static_cast<T>:强迫隐式转换(无法const转为non-const,const_case<T>可以)

    详细见另外一个blog

    28、

  • 相关阅读:
    LeetCode 1122. Relative Sort Array (数组的相对排序)
    LeetCode 46. Permutations (全排列)
    LeetCode 47. Permutations II (全排列 II)
    LeetCode 77. Combinations (组合)
    LeetCode 1005. Maximize Sum Of Array After K Negations (K 次取反后最大化的数组和)
    LeetCode 922. Sort Array By Parity II (按奇偶排序数组 II)
    LeetCode 1219. Path with Maximum Gold (黄金矿工)
    LeetCode 1029. Two City Scheduling (两地调度)
    LeetCode 392. Is Subsequence (判断子序列)
    写程序判断系统是大端序还是小端序
  • 原文地址:https://www.cnblogs.com/2012harry/p/3968321.html
Copyright © 2011-2022 走看看