条款 1:尽可能用 const 和 inline 而不用#defineios
#define 用 const ,inline程序员
template<class T>函数
inline const T& max(const T& a, const T& b) { return a > b ? a : b; }性能
<iostream>this
条款 2:尽可能用<iostream>而不用<stdio.h>指针
条款 3:尽可能用 new 和 delete 而不用 malloc 和 free对象
条款 4:尽可能使用 C++风格的注释继承
#define LIGHT_SPEED 3e8 // m/sec (in a vacuum)接口
行尾的注释居然成为了宏的一部分!内存
内存管理:正确地获得它和有效地使用它。
条款 5:对应的 new 和 delete 要采用相同的形式
条款 6:析构函数里对指针成员调用 delete
条款 7:预先准备好内存不够的状况 set_new_handler
条款 8. 写 operator new 和 operator delete 时要遵循常规
返回值的部分很简单。若是内存分配请求成功,就返回指向内存的指针;
若是失败,则遵循条款 7 的规定抛出一个 std::bad_alloc 类型的异常。
条款 9. 避免隐藏标准形式的 new
条款 10. 若是写了 operator new 就要同时写 operator delete
内存泄露的缘由在于内存分配后指向内存的指针丢失了。
内存池
自定义的内存管理程序能够很好地改善程序的性能
构造函数控制对象 生成时的基本操做,并保证对象被初始化;析构函数摧毁一个对象并保证它被 完全清除;
条款 11: 为须要动态分配内存的类声明一个拷贝构造函数和一个赋值操做符
a: data——> "Hello\0" b: data——> "World\0"
b = a;
第一,b 曾指向的内存永远不会被删除,于是会 永远丢失。这是产生内存泄漏的典型例子。第二,如今 a 和 b 包含的指针指向 同一个字符串,那么只要其中一个离开了它的生存空间,其析构函数就会删除 掉另外一个指针还指向的那块内存。
用 delete 去删除一个已经被删除的指针,其结果是不可预测的。
解决这类指针混乱问题的方案在于,只要类里有指针时,就要写本身版本 的拷贝构造函数和赋值操做符函数。
条款 12: 尽可能使用初始化而不要在构造函数里赋值
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr ) : name(initName), ptr(initPtr)
{}
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr) {
name = initName;
ptr = initPtr; }
const 成员只能被初始化,不能被赋值。
条款 13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同
若是想弄清楚对象被初始化时究竟是怎么作的,请确信你 的初始化列表中成员列出的顺序和成员在类内声明的顺序一致。
条款 14: 肯定基类有虚析构函数
一个类想跟踪它有多少个对象存在。一个简单的方法是建立一个静 态类成员来统计对象的个数。这个成员被初始化为 0,在构造函数里加 1,析 构函数里减 1。
当且仅当类里包含至少一个虚函数的时候才去声明 虚析构函数。
条款 15: 让 operator=返回*this 的引用
一个错误是让 operator=返回 void
另外一个常犯的错误是让operator=返回一个const对象的引用
条款 16: 在 operator=中对全部数据成员赋值
条款 17: 在 operator=中检查给本身赋值的状况
条款 18: 争取使类的接口完整而且最小
类的用户接口是指使用这个类的程序员所能访问获得的接口。
条款 19: 分清成员函数,非成员函数和友元函数
条款 20: 避免 public 接口出现数据成员
条款 21: 尽量使用 const
条款 22: 尽可能用“传引用”而不用“传值”
为避免这种潜在的昂贵的开销,就不要经过值来传递对象
条款 23: 必须返回一个对象时不要试图返回一个引用
条款 24: 在函数重载和设定参数缺省值间慎重选择
条款 25: 避免对指针和数字类型重载
void f(int x);
void f(string *ps);
f(0); // 调用 f(int)仍是 f(string*)?
条款 26: 小心潜在的二义性
条款 27: 若是不想使用隐式生成的函数就要显式地禁止它
条款 28: 划分全局名字空间
条款 29: 避免返回内部数据的句柄
条款 31: 千万不要返回局部对象的引用,也不要返回函数内部用 new 初始化的 指针的引用
条款 33: 明智地使用内联
条款 34: 将文件间的编译依赖性降至最低
条款 35: 使公有继承体现 "是一个" 的含义
写下类 D("Derived" )从类 B("Base")公有继承时,你其实是在告 诉编译器(以及读这段代码的人):类型 D 的每个对象也是类型 B 的一个对 象,但反之不成立;
条款 36: 区分接口继承和实现继承
定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
条款 37: 决不要从新定义继承而来的非虚函数
条款 38: 决不要从新定义继承而来的缺省参数值
缺省参数值要相同
虚函数是动态绑定的:虚函数经过哪一个对象被调用,具体被调,用的函数就由那个对象的动态类型决定:
条款 39: 避免 "向下转换" 继承层次
从一个基类指针到一个派生类指针 ---- 被称为 "向下 转换"
条款 40: 经过分层来体现 "有一个" 或 "用...来实现"
条款 41: 区分继承和模板
条款 42: 明智地使用私有继承
条款 43: 明智地使用多继承
条款 44: 说你想说的;理解你所说的
条款 45: 弄清 C++在幕后为你所写、所调用的函数
条款 46: 宁肯编译和连接时出错,也不要运行时出错
条款 47: 确保非局部静态对象在使用前被初始化
条款 48: 重视编译器警告
条款 49: 熟悉标准库
条款 50: 提升对 C++的认识