effective C++ 条款01 to 条款04
2010-11-17 16:27
417 查看
条款01:
知道C++的4个语言层次:
1、C,就是传统C语言的一套东西在C++中都可以运用
2、Object-Oriented C ++ 就是面向对象的支持在C++中的体现(继承啊,多态啊,都属于这个话题的范畴)
3、template C++ 这个地方大部分人就不熟悉了,泛型编程,主要是不常用,就是所有的东西都是模板,与具体的类型没有关系
4、STL,一个库,可以方便用户编程,很多常用的数据结构进行了封装,方便到标准库的很大一部分都被STL占据
所以,要想让C++高效,首先我们必须弄清楚我们现在是处在上面4种的哪一个语言层次,每一个语言层次我们关注点是不同,高效编程的规则也不一样,例如,对于内置类型:pass by value比较好,对于用户自定义,用pass by reference to const比较好,对于STL,还是得用pass by value 。所以,想编牛逼的程序,先弄清楚自己在用C++的什么层次
条款02:
#define 基本可以下岗了,C中的宏很多都有替代方法啦
#define ASPECT_RATIO 1.653 这个不好,为什么呢?记号名称ASPECT_RATIO不能被编译器看见,不方便debug,盲目宏替换导致目标代码出现多份,没有类型检查,替代方法:const float ASPECT_RATIO = 1.653
#define不能搞出类的专属常量,但是const+static可以
class GamePlayer{
private :
static const int NumTurns = 5 ; //声名式,并非定义式
}
如果非要一个定义式,则在实现文件,非头文件中写:const int GamePlayer::NumTurns = 5
如果,类的某个成员还依赖NumTurns , 那么,就用class里的enum
class GamePlayer{
private :
enum( NumTurns = 5) ;
int score[NumTurns] ;
}
宏可以搞小函数,但是麻烦的YB,记得加各种括号,还要想到各种安全性的东西,替代方法就是用inline
当然,预处理器还是有用的,#include , #ifndef 之类还是很有用的
条款03:甩用const
const就是加上一个约束,不能改变
1、关键字在星号左边,表示被指物事常量
2、关键字在星号右边,表示指针自身是常量
3、const vector<int>::iterator iter 表示iter自身是常量,不能瞎指
4、vector<int>::const_iterator iter 表示iter所指对象是常量,不能通过iter改变
上面只是一般的东西,const最狠的地方是函数的声明(参数,返回值,函数自身)
参数和返回值都比较好理解,关键是函数自身
1、关键点:两个成员函数如果只是常量性不同,可以实现重载。改善C++要用pass by reference to const,如果有相应的const函数多好。
2、const函数,只能操作类的const成员,但是。如果给变量加上mutable关键字,那么,const成员函数也能搞他了
3、应当运用const成员函数实现出其non-const的孪生兄弟版本,不能反过来
条款04:初始化要牢记
用变量,一定先初始化,否则,麻烦不尽
内置对象,显示初始化,类对象,通过构造函数初始化
核心概念:
1、类对象的初始化,在进入类的构造函数之前就已经完成了,所以,如果在构造函数中用赋值,相当于1次default ctor + 1此copy assignment , 如果直接用初始化列表,那么就是1次copy ctor 或者 1此default ctor , 显然后者效率更高。
2、构造函数的运行顺序是先祖先,后儿子,析构相反,自己中按照类中变量的声明顺序初始化,而不是初始化列表中的顺序
3、不同编译单元内定义的non-local static 对象的初始化次序
假设:a.h : string s = "caiyichao"
b.h : #include "a.h"
extern string s
string s_1(s)
除非先有了s否则,s_1是不能被正确初始化,但是这种先后关系是不能被保证的。怎么办
以local static 对象替换 non-local static
a.h : string createS()
{
static string s("caiyichao") ;
return s ;
}
b.h : #include "a.h"
string createS_1()
{
static string s_1( createS() ) ;
return s_1
}
可以这么做的原因是:C++保证,函数内的local static对象会在函数被调用期间,首次遇上该对象的定义式时被初始化
知道C++的4个语言层次:
1、C,就是传统C语言的一套东西在C++中都可以运用
2、Object-Oriented C ++ 就是面向对象的支持在C++中的体现(继承啊,多态啊,都属于这个话题的范畴)
3、template C++ 这个地方大部分人就不熟悉了,泛型编程,主要是不常用,就是所有的东西都是模板,与具体的类型没有关系
4、STL,一个库,可以方便用户编程,很多常用的数据结构进行了封装,方便到标准库的很大一部分都被STL占据
所以,要想让C++高效,首先我们必须弄清楚我们现在是处在上面4种的哪一个语言层次,每一个语言层次我们关注点是不同,高效编程的规则也不一样,例如,对于内置类型:pass by value比较好,对于用户自定义,用pass by reference to const比较好,对于STL,还是得用pass by value 。所以,想编牛逼的程序,先弄清楚自己在用C++的什么层次
条款02:
#define 基本可以下岗了,C中的宏很多都有替代方法啦
#define ASPECT_RATIO 1.653 这个不好,为什么呢?记号名称ASPECT_RATIO不能被编译器看见,不方便debug,盲目宏替换导致目标代码出现多份,没有类型检查,替代方法:const float ASPECT_RATIO = 1.653
#define不能搞出类的专属常量,但是const+static可以
class GamePlayer{
private :
static const int NumTurns = 5 ; //声名式,并非定义式
}
如果非要一个定义式,则在实现文件,非头文件中写:const int GamePlayer::NumTurns = 5
如果,类的某个成员还依赖NumTurns , 那么,就用class里的enum
class GamePlayer{
private :
enum( NumTurns = 5) ;
int score[NumTurns] ;
}
宏可以搞小函数,但是麻烦的YB,记得加各种括号,还要想到各种安全性的东西,替代方法就是用inline
当然,预处理器还是有用的,#include , #ifndef 之类还是很有用的
条款03:甩用const
const就是加上一个约束,不能改变
1、关键字在星号左边,表示被指物事常量
2、关键字在星号右边,表示指针自身是常量
3、const vector<int>::iterator iter 表示iter自身是常量,不能瞎指
4、vector<int>::const_iterator iter 表示iter所指对象是常量,不能通过iter改变
上面只是一般的东西,const最狠的地方是函数的声明(参数,返回值,函数自身)
参数和返回值都比较好理解,关键是函数自身
1、关键点:两个成员函数如果只是常量性不同,可以实现重载。改善C++要用pass by reference to const,如果有相应的const函数多好。
2、const函数,只能操作类的const成员,但是。如果给变量加上mutable关键字,那么,const成员函数也能搞他了
3、应当运用const成员函数实现出其non-const的孪生兄弟版本,不能反过来
条款04:初始化要牢记
用变量,一定先初始化,否则,麻烦不尽
内置对象,显示初始化,类对象,通过构造函数初始化
核心概念:
1、类对象的初始化,在进入类的构造函数之前就已经完成了,所以,如果在构造函数中用赋值,相当于1次default ctor + 1此copy assignment , 如果直接用初始化列表,那么就是1次copy ctor 或者 1此default ctor , 显然后者效率更高。
2、构造函数的运行顺序是先祖先,后儿子,析构相反,自己中按照类中变量的声明顺序初始化,而不是初始化列表中的顺序
3、不同编译单元内定义的non-local static 对象的初始化次序
假设:a.h : string s = "caiyichao"
b.h : #include "a.h"
extern string s
string s_1(s)
除非先有了s否则,s_1是不能被正确初始化,但是这种先后关系是不能被保证的。怎么办
以local static 对象替换 non-local static
a.h : string createS()
{
static string s("caiyichao") ;
return s ;
}
b.h : #include "a.h"
string createS_1()
{
static string s_1( createS() ) ;
return s_1
}
可以这么做的原因是:C++保证,函数内的local static对象会在函数被调用期间,首次遇上该对象的定义式时被初始化
相关文章推荐
- 《Effective C++ 3》01 让自己习惯C++ 条款:01-04
- 【Effective c++ 读书笔记】条款01 视 C++ 为一个语言联邦
- Effective C++:条款01
- effective c++ 条款23 perfer nonmember nonfreind function to member function
- Effective C++ 条款10: 令operator= 返回一个reference to *this
- Effective C++ -----条款20:宁以pass-by-reference-to-const替换pass-by-value Prefer pass-by-reference-to-const to pass-by-value
- 读书笔记《Effective c++》 条款10 令operator= 返回一个reference to *this
- 《Effective C++》——条款20:宁以pass-by-reference-to-const替换pass-by-value
- effective C++ 条款32 to 条款40
- Effective C++_笔记_条款04_确定对象被使用之前已先被初始化
- [Effective C++]条款01:视C++为一个语言联邦
- Effective C++读书笔记版-条款01,02
- Effective C++ 条款04:确定对象被使用前已经先被初始化
- effective C++ 条款13 to 条款17
- Effective C++ 条款20 宁以pass-by-reference-to-const替换pass-by-value
- 读书笔记《Effective c++》 条款04 确定对象被使用前已经被初始化
- 【Effection C++】读书笔记 条款01~条款04
- Effective C++:条款04
- 《Effective C++》学习笔记条款20 宁以pass-by-reference-to-const替代psss-by-value
- 《Effective C++》学习笔记条款10 令operator= 返回一个reference to *this