c++程序设计(Effective C++)学习笔记

Effective C++是一本非常好的进阶书,里面很多思想是平时大家很难或者很不容易去思考或想明白的,在找工作之前,也翻阅了两遍此书,并偶尔留下了些许笔记,今天贴到这里,以供参考。

1、强制类型转换

    static_cast:完成相关类型之间的转换,编译器能对static_cast做一些小的类型检查,运行时不检查;
    reinterpret_cast:处理互不相关的类型之间的转换,很危险;
    dynamic_cast:运行中检查的转换形式;
    const_cast:去除const和volatile限定符的转换形式;

2、静态变量
    局部变量将在运行线程到达其定义的时候进行初始化,并且会在每个函数调用中产生一份局部变量的副本。而如果一个局部变量被声明为static,那么将只有唯一的一个静态分配对象,用于该函数的所有调用中,这个静态变量将在执行线程第一次到达其定义时进行初始化。—— 初始化一次,一直存在,可以为函数提供一种“存储器”,使我们不必引入可能被其他函数访问或者破坏的全局变量。(只能在函数内部访问)

3、const& 与non_const&参数传递
    修改引用参数的函数将会使程序很难阅读,因此,在传递引用参数时,除非明确要修改引用参数,否则应该传递const& 引用参数; 字符串、常量、需要转换的参数都可以传递给const&参数,但不能传递给非const的引用参数
原理如下:
        double dval = 3.14
        const int& ival = dval;//this is legal for const references only
        编译器会产生如下代码:
        int temp = dval;
        const int& ival = temp;
        因此,如果是传递给非const引用,如果修改ival,则修改的是temp临时变量,而不是dval,这会让程序员陷入困境之中,因此,非const引用只能能绑定到与该引用同类型的对象上,而const引用,可以绑定到不同但相关的类型的对象或者绑定到右值(立即数)

例如:
    float fsqrt(const float&);

    void g(double d)
    {
        float r = fsqrt(2.0f);    //传递的是保存2.0f的临时变量的引用
        r = fsqrt(r);    //传递r的引用
        r = fsqrt(d);    //传递的是保存float(d)的临时变量的引用
    }
     而对non_const引用不允许做类型转换,这样能够帮助我们避免一种引入临时变量而产生的可笑错误。例如:
    void updata(float& i);
    
    void g(double d, float r)
    {
        update(2.0f);    //错误:non const参数,产生临时对象可能被修改
        update(r);    //传递r的引用
        update(d);    //错误:要去类型转换,产生临时对象可能被修改
    }

4、异常
异常机制是c++中用于 将错误报告和错误处理分离开的手段。
一、一方报告出那些无法在局部解决的错误;
二、另一方处理那些在其他地方检查出的错误。
    即一方抛出异常,一方捕获并处理异常。抛出异常采用throw,捕获采用catch,例如:
     struct  Range_error{
        int i;
        Range_error(int ii){i = ii;}
    };
    char to_char(int i)
    {
        if(i<min || i>max)
        {
            throw Range_error(i);
        }
        return i;
    }
    函数to_char()返回一个具有数值i的char,或者抛出一个Range_error异常。如果函数发现了一个无法处理的问题,就抛出异常,而希望他的调用者能够处理这个问题。如果想调用to_char()并捕获它可能抛出的异常,我们可以写:
     void g(int i)
    {
        try{
            char c = to_char(i);
            //...
            }
        catch(Range_error){//异常处理器
            cerr<<"oops\n";
        }
    }

5、析构函数与构造函数注意事项
1)析构函数可以是虚函数,并且在必定做父类的时候,析构函数必须声明为虚函数才可以得到期望的行为;                   
2)析构函数还可以是纯虚函数,一般声明纯虚函数是为了得到抽象类,纯虚函数可以有实现;
3)构造函数不能是虚函数,也不能是纯虚函数,在构造函数中,也不能调用虚函数,因为在父类的构造过程中,多态是被disable的,不能得到期望的行为;
4)同样,析构函数也不能调用虚函数;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值