effective c++笔记-第一篇

1.声明与定义

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

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

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

有一个函数:

void Fun(B obj);

|调用|说明|有explicit|无explicit|
|-------------|--------------|--------------|
|Fun(2)|隐式转换|错|对|
|Fun(B(2))|显示转换|对|对
|B b; Fun(b);||对|对|

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

3.copy构造函数

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

4.尽量传引用,不传值

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

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

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

6.预处理器处理

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

7.尽量使用const

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

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

  • 准则:确保对象构造函数把每个成员都初始化
  • 编译器的不明确行为
    • **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;
}

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

你可能感兴趣的:(c++学习总结,读书渡己)