作者 Scott Meyers  翻译作者 侯捷 C++ 神牛 台湾人

术语:

1.explicit

C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。但他们仍然可以用来进行显示转换。

示例:

class Test1
{
public:
Test1(int n) { num = n; } //普通构造函数
private:
int num;
};
class Test2
{
public:
explicit Test2(int n) { num = n; } //explicit(显式)构造函数
private:
int num;
};
int main()
{
Test1 t1 = ; //隐式调用其构造函数, 成功
Test2 t2 = ; //编译错误,不能隐式调用其构造函数
Test2 t3(); //显式调用成功
return ;
}

2 undefined behavior

 int *p=; //p其实是一个NULL指针
std::cout<<*p;//对一个NULL指针取值会导致不明确行为。

条款一:

封装 encapsulation、继承 inheritance、多态 polymorphism

在STL中,迭代器和函数对象都是在C指针之上塑造的,所以对STL的迭代器和函数对象而言,旧式的pass-by-value守则再次适用。

C++高效编程守则视状况而变化,取决于你适用C++的那一部分。 C、Object-Oriented C++、Template C++、STL

条款二:

scope 作用域

enum hock  一个属于枚举类型的数值可权充ints被适用。//权充 (暂且充当)

取一个const的地址是合法的,但取一个enum的地址不合法。

class  GamePlayer
{
private:
enum {NumTurns=};
int scores[NumTurns];
.....
};

宏的不可思议:

 #include<iostream>

 #define call(a,b) (a)>(b)?(a):(b)
int main()
{ int lv1=,rv1=;
int lv2=,rv2=;
int result1=call(++lv1,rv1); //lv1累加2次为7
int result2=call(++lv2,rv2+); //lv2累加1次为6
std::cout<<result1<<" "<<lv1<<std::endl;
std::cout<<result2<<" "<<lv2<<std::endl;
system("pause"); return ;
}

条款三:

1.STL中iterator的const用法:

      std::vector<int> vec;
...
const std::vector<int>::iterator iter=vec.begin();//iter 的作用像个T* const
*iter=; //没问题,改变iter所指物
++iter; //错误! iter是const
std::vector<int>::const_iterator cIter=vec.begin(); //cIter的作用像个const *T
*cIter=; //错误! *cIter是const
++cIter; //没问题,改变cIter

2.const成员函数不可以更改对象内任何non-static成员变量。

3.利用C++的一个与const相关的摆动场:mutable(可变的)释放掉non-static成员变量的bitwise constness约束。

 mutable bool lengthIsValid;
CTextBlock::length() const//这些成员变量可能总是会被更改,即使在const成员函数内。
{
lengthIsValid=false;
}

4.const_cast: 通常被用来将对象的常量性转除。也是唯一有此能力的C++-style转型操作符。

static_cast:用来强迫隐式转换(implicit conversions),如将non-const对象转为const对象,或者int转为double。

条款四:确定对象被使用前已先被初始化

1.构造函数最好使用成员初始化而不要在构造函数本体内使用赋值操作,初始值列列出的成员变量,其排序次序应该和他们在class类中的声明次序相同。

2.base classess 更早于其derived classes被初始化,而class的成员变量总是以其声明次序被初始化。

ABEntry::ABEntry(const std::string &name,const std::string &address,const std::list<PhoneNumber> &phones)

{

theName=name;   //这些都是赋值(assignment)而非初始化(initialization)

theAddress=address;  //这会导致首先调用default构造函数为theName,theAddress,thePhones设初值,然后立刻再对它们赋予新值

thePhones=phones;    //default构造函数的一切作为被浪费了

numTimeConsulted=0;

}

ABEntry::ABEntry(const std::string &name,const std::string &address,const std::list<PhoneNumber> &phones)

:theName(name),theAddress(address),thePhones(phones),numTimeConsulted(0);

{

//这些都是初始化(initialization)而非赋值(assignment)

}

条款五:了解C++摸摸编写并调用那些函数

一般不能对内含reference成员或者内含const的classes支持赋值操作。如果你要这么做的话就必须要自己定义copy assignment 操作符。

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

例如如果不需要拷贝构造函数和copy assignment 操作符时,一旦有人调用他们时却会自动默认构造出来。所以只能将函数声明为private而且故意不实现他们。

class HomeForSale

{

public:

...

private:

HomeForSale(const HomeForSale &);  //只有声明

HomeForSale & operator=(const HomeForSale &);//没有实现

}

条款七:为多态基类声明vitrual析构函数

1.任何class只要有virtual函数几乎确定应该也有一个virtual析构函数。如果一个class中不含virtual函数,通常表示它并不意图被用做一个base class.而当class不企图被当作base class,令其析构函数为virtual 往往是个馊主意。

2.只有当class内含至少一个virtual函数才为它声明virtual析构函数。

3.polymorphic(带多态性质)base class应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。

4.Classes的设计目的如果不是作为base class使用,或不是为了具备多态性就不该声明virtual析构函数。

    

Effective C++ 读书笔记(1-7)的更多相关文章

  1. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

  2. Effective STL读书笔记

    Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...

  3. effective c++读书笔记(一)

    很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.3 ...

  4. Effective Java读书笔记完结啦

    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

  5. Effective java读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...

  6. Effective Objective-C 读书笔记

    一本不错的书,给出了52条建议来优化程序的性能,对初学者有不错的指导作用,但是对高级阶段的程序员可能帮助不是很大.这里贴出部分笔记: 第2条: 使用#improt导入头文件会把头文件的内容全部暴露到目 ...

  7. 【Effective C++读书笔记】序

    C++ 是一个难学易用的语言! [C++为什么难学?] C++的难学,不仅在其广博的语法,以及语法背后的语义,以及语义背后的深层思维,以及深层思维背后的对象模型: C++的难学还在于它提供了四种不同而 ...

  8. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  9. Effective C++读书笔记(转)

    第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会 ...

  10. Effective C++ 读书笔记 名博客

    https://www.cnblogs.com/harlanc/tag/effective%20c%2B%2B/default.html?page=3

随机推荐

  1. (NO.00002)iOS游戏精灵战争雏形(八)

    子弹的初始化工作前2篇基本做好了,下面就是如何射出子弹. 通常来说,子弹射向目标对象,需要走一条直线.直线由2点定位,分别为发射点和目标点. 发射点就是开枪精灵自身的位置,目标点则为敌方精灵的位置,大 ...

  2. (NO.00001)iOS游戏SpeedBoy Lite成形记(十六)

    接上篇,我们实现菜单窗口的弹出和关闭功能,首先在打开GameScene.m,添加必要的实例变量: __weak PopupLayer *_popupLayer; 再添加2个新方法: -(void)re ...

  3. React native开发中常见的错误

    react native环境搭建请移步:react native环境搭建 这里说说react native创建完成之后,运行中出现的常见问题, 问题1: java.lang.RuntimeExcept ...

  4. volatile和synchronized的区别和联系

    volatile 它所修饰的变量不保留拷贝,直接访问主内存中的.   在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器).为了性能,一个线程会在自己的mem ...

  5. E-JSON数据传输标准

    简介 E-JSON的设计目标是使业务系统向浏览器端传递的JSON数据保持一致,容易被理解和处理,并兼顾传输的数据量.E-JSON依托于http协议(rfc2616)与JSON数据交换格式(rfc462 ...

  6. hadoop 数据倾斜

    数据倾斜是指,map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有 ...

  7. JSP 知识基本

    from:http://blog.csdn.net/caipeichao2/article/details/38589293 more:http://www.2cto.com/kf/web/jsp/4 ...

  8. java实现Quartz定时功能

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/49975443 最近在学习定时相关的技术.当前,几乎所有的互 ...

  9. mybatis 开发环境搭建

    不说废话直接上代码,首先看下我的目录机构: 红色部分,表明你所需的jar包,已经配置文件. 创建用户表,以及插入数据. create table books(id int (11) not null ...

  10. 关于masm中PTR伪指令的一点思考

    在masm中,PTR伪指令只能修饰内存变量类型,因为任何寄存器的大小都是已知的且不能改变的(如果PTR修饰的是寄存器,则它修饰的是寄存器本身而不是其指向的内容)所以不能用PTR改变寄存器的大小,例如: ...