effective c++读书笔记

条款一:

把c++视为一个联邦式语言

条款二:

const,enum,inline替换#define

类里面的常量:两种方法:

第一种(对于某些旧式编译器不支持):在类里面声明:static const int NUM = 5;注意这是声明,如果需要取值还需在类外定义:const int 类::NUM;注意这里不需要在赋址。很奇怪!!

第二种:在类里面声明:static const int NUM ,在类外面定义:static const int NUM =1;

其次介绍了枚举的用法:在类里面 enum{NUM = 5};

条款三:

尽可能使用const

char greeting[] = "hello"

const char * p = greeting;//数组不能修改

char * const pp = greeting;//指针只能指向该数组

编译器强制实施bitwise constness,const 成员函数无法改变非const成员变量,除非成员变量被声明为mutable

const成员变量的初始化实在构造函数中!!

static成员变量初始化在类的外面:int const_test::tt = 0;变量在这里定义,不能放在初始化列表中

const int i=0:

int x =i;//ok

int & x=i;//error

const int & x = i;//ok

class Ration{。。。};

const Ration operator* (const Ration& lhs,const Ration& rhs);

Ration a,b,c;

(b*c)=a;//如果不是const,就会出现问题

条款四:

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

对象的成员变量初始化发生在进入构造函数本体之前,初始化列表。

自定义类型的成员变量自动调用default构造函数

初始化顺序与成员变量声明顺序一致

local static和non-local static:

不同编译单元的non_local static初始化顺序是不定的,因此不能在一个编译单元使用另一个编译单元的non_local static对象

class FileSystem{...};

FileSystem& tfs()

{

static FileSystem fs;

return fs;

}

class Directory{...};

Directory::Directory()

{

tfs().成员函数()

}

Directory & tempDir()

{

static Directory td;

return td;
}

对于初始化问题:分为c形式和c++形式两个部分考虑,如int 型,如果没有给它初始化,那就没有初始值,如果是vector,会调用default构造。

静态全局变量有以下特点:

  • 该变量在全局数据区分配内存;
  • 未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
  • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
关于静态成员函数,可以总结为以下几点:
  • 出现在类体外的函数定义不能指定关键字static;
  • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
  • 非静态成员函数可以任意地访问静态成员函数和静态数据成员;
  • 静态成员函数不能访问非静态成员函数和非静态数据成员;
  • 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
  • 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
    <类名>::<静态成员函数名>(<参数表>)
    调用类的静态成员函数。

条款五:

构造/析构/赋值运算

在一个内含“reference”成员或"const"成员的类,编译器不会为其生成copy assignment操作符

base classes将copy assignment声明为private,编译器不会为其生成copy assignment操作符

条款六

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

将相应的成员函数声明为private并且不实现

使用uncopyable这样的base class

条款七

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

如果虚构函数被声明为pure virtual,还需在类外面提供一份定义:类名::~类名(){}

最深层的class析构函数最先调用

条款八

别让异常逃离析构函数

两个异常同时存在,程序或结束执行或导致不明确行为

析构函数中:

try{db.close();}

catch{...}

{

记录

 std::abort();

}

try{db.close();}

catch{...}

记录

}

条款九

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

在base class构造期间,virtual函数不是virtual函数

通过一个static成员函数将derived class信息传递给base class。例子p51

explicit:关键字explicit可以禁止“单参数构造函数”被用于自动类型转换

条款10

在operator=返回reference to * this

条款11

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

自我赋值安全性和异常安全性

Widget & Widget::operator=(const Widget& rhs)

{

Bitmap * porig = pb;

pb = new Bitmap(*rhs.pb);

delete porig;

return * this;

}

使用swap函数

条款12

复制对象时勿忘其每一个成分

当自己写copy函数时,derived class要在初始列表里面调用base class的copy构造函数,operator=()里面也要调用base class的operator=.eg:base_class::operator=()(rhs)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值