条款3: 尽量用new和delete而不用malloc和free
malloc和free不调用构造和析构函数;
e.g. 给一个包含 10 个string 对象的数组分配空间
1
2
|
string *stringArray1 =
static_cast
<string*>(
malloc
(10 *
sizeof
(string)));
string *stringArray2 =
new
string[10];
|
>stringArray1指向可以容纳10个string对象的空间, 但内存没有创建对象;
stringArray2指向包含10个完全构造好的string对象的数组, 每个对象可以操作;
1
2
|
free
(stringArray1);
delete
[] stringArray2;
|
>假设stringArray1数组里的对象进行了初始化, free释放stringArray1指向的内存, 但内存里的string对象不会调用析构函数, 如果string对象已经分配了内存, 这些内存将丢失;
当delete[]时, 数组里的每个对象都会在内存释放前调用析构函数;
不要混用new/delete和malloc/free; 后果是不可预测的: 可能在开发阶段工作良好, 测试阶段良好, 但在不确定的情况下发生严重问题;
new/delete和malloc/free不兼容; e.g.
<string.h>里的strdup()函数, 得到一个char*字符串然后返回其拷贝:
1
|
char
* strdup(
const
char
*ps);
// 返回ps 所指的拷贝
|
某些情况C和C++用同一版本的strdup(), 函数内部用malloc分配内存, C++程序员会在调用strdup()后忘记对返回的指针进行free;
有些地方专门为C++重写strdup(), 在函数内部调用new, 这样就需要在调用strdup()后使用delete; (移植性较差)
要确保malloc对应free, new对应delete; 在使用基于malloc和free写成的C库时, 最好不用自己free和malloc库的内存;
条款4 尽量使用C++风格的注释
C++行尾注释法:
1
2
3
|
// int temp = a; // swap a and b
// a = b;
// b = temp;
|
C风格注释:
1
2
3
4
|
/* int temp = a; /* swap a and b */
a = b;
b = temp;
*/
|
>嵌在代码块里的注释会提前结束掉整个代码块的注释;
C风格的注释在C和C++编译器都要处理的头文件中无法替代;
有些老的专门为C写的预处理程序不识别C++风格的注释:
1
|
#define LIGHT_SPEED 3e8 // m/sec (in a vacuum)
|
>这种情况下注释会变成宏的一部分;
---从C转向C++ End---