effective c++笔记-第一篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liunan199481/article/details/81984180

声明与定义

  • 声明:揭示函数/变量的签名,参数和返回类型
    • 如:int fun(int)
  • 定义:实际是为各对象分配内存

在构造函数前使用explicit关键字

class B
{
    public:
        B(int x){}
};

有一个函数:

void Fun(B obj);
调用 说明 有explicit 无explicit
Fun(2) 隐式转换
Fun(B(2)) 显示转换
B b; Fun(b);

由此可以看出,explicit可以阻止隐式转换,这是好的,因为隐式转换大多数情况不是我们的预期

copy构造函数

  • 拷贝构造函数的目的是以同类型的对象初始化自我
  • 继续使用上面的类B
    • B b1(2) //调用默认构造函数
    • B b2(b1)//调用copy构造函数
    • B b3 = b1//调用copy构造函数
    • b2 = b1//调用copy操作符
    • 后面2个有区别是因为b3是未存在,b2已存在了

尽量传引用,不传值

  • 因为如果传值的话,实参的值赋值给形参要调用copy构造函数,结束还要析构掉,如果对象有父类和子类,想一想构造函数和析构的代价会更大

尽量用const、enum、inline替换#define

  • 我们知道#define是预处理的时候直接替换的,编译时的符号表不存在变量的符号,所有如果出错是不好定位到那个变量出错,可能只能看到出错的值。例如别人写的文件里的出错了,是因为它#define的一个变量出错,而你使用了他的文件,出错,完全定位不到哪里出错。
  • 所以如果#define定义一个常量,完全可以用const取代
  • enum也是类似,可以为常量取一个别名,易读
  • inline函数可以提高运行速度,因为它直接嵌入代码中,所以代码段要小

预处理器处理

#define、#include、#ifdef/#endif、etc

尽量使用const

  • 原因:许多编译器对const对象进行了优化,运行速度变快
  • const可使用的情况:
    • const可修饰类内static或non-static变量
    • 可修饰类外global或namespace作用域的对象
    • 可修饰文件、函数、块作用域内被声明为static的对象
  • const成员变量:
    • 明示那个函数可改动对象内容
    • 使操作const成为可能(不太懂)
  • 成员函数的常量性不同可被重载
    总结:
  • 某些变量或对象声明为const,编译器可帮助侦错
  • non-const版本调用const版本,可避免代码重复

确定对象使用前先被初始化

  • 准则:确保对象构造函数把每个成员都初始化
  • 编译器的不明确行为
    • int x;对于x,编译器有时会把x初始化为0,有时不会
  • 内置类型的初始化
    • 鉴于不确定行为,所以初始化操作的责任落在人身上
  • 自定义类型
    • 初始化责任落在类本身,在构造函数进行初始化
    • 赋值和初始化的区别
class B
{
    public:
        B(int x):m_a(x){}
    private:
        int m_a;
}

上面这个使初始化

class B
{
    public:
        B(int x){
            m_a = x;
    }
    private:
        int m_a;
}

上面这个是赋值
赋值是在构造函数体内完成的,它等于是构造函数已经初始化了,再给类成员赋值,而初始化是在初始化列表中给成员变量初始化,相当于在自身初始化的时候给成员也初始化了,比起赋值,效率坑定高了很多。

猜你喜欢

转载自blog.csdn.net/liunan199481/article/details/81984180