您的位置:首页 > 编程语言 > C语言/C++

高质量C++/C 编程指南小结

2007-10-27 10:49 295 查看
【规则1-2-1】为了防止头文件被重复引用,应当用ifndef/define/endif 结构产生预处
理块。
【规则1-2-2】用 #include <filename.h> 格式来引用标准库的头文件(编译器将从
标准库目录开始搜索)。
【规则1-2-3】用 #include “filename.h” 格式来引用非标准库的头文件(编译器将
从用户的工作目录开始搜索)。
【建议1-2-1】头文件中只存放“声明”而不存放“定义”
【规则2-3-1】关键字之后要留空格。象const、virtual、inline、case 等关键字之后
至少要留一个空格,否则无法辨析关键字。象if、for、while 等关键字之后应留一个
空格再跟左括号‘(’,以突出关键字。
【规则2-3-2】函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。
【规则2-3-3】‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。
【规则2-3-4】‘,’之后要留空格,如Function(x, y, z)。如果‘;’不是一行的结束
符号,其后要留空格,如for (initialization; condition; update)。
【规则2-3-5】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,
如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元
操作符的前后应当加空格。
【规则2-3-6】一元操作符如“!”、“~”、“++”、“--”、“&”(地址运算符)等前后不
加空格。
【规则2-3-7】象“[]”、“.”、“->”这类操作符前后不加空格。
【规则3-1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持一致。
例如Windows 应用程序的标识符通常采用“大小写”混排的方式,如AddChild。而
Unix 应用程序的标识符通常采用“小写加下划线”的方式,如add_child。
【规则3-1-6】变量的名字应当使用“名词”或者“形容词+名词”。
【规则3-1-7】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。
类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。
【规则3-2-1】类名和函数名用大写字母开头的单词组合而成。
【规则3-2-2】变量和参数用小写字母开头的单词组合而成。
【规则3-2-3】常量全用大写的字母,用下划线分割单词。
【规则3-2-4】静态变量加前缀s_(表示static)。
【规则3-2-5】如果不得已需要全局变量,则使全局变量加前缀g_(表示global)。
【规则3-2-6】类的数据成员加前缀m_(表示member),这样可以避免数据成员与
成员函数的参数同名。
【建议4-4-1】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的
循环放在最外层,以减少CPU 跨切循环层的次数。
【规则5-2-1】在C++ 程序中只使用const 常量而不使用宏常量,即const 常量完
全取代宏常量。
【规则5-3-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义
文件的头部。为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。
【规则5-3-2】不能在类声明中初始化const 数据成员。const 数据成员的初始化只能在类构造函数的初始化表中进行。应该用类中的枚举常量来实现整个类中都恒定的常量。
【规则6-1-3】如果参数是指针,且仅作输入用,则应在类型前加const,以防止该
指针在函数体内被意外修改。一般地,应将目的参数放在前面,源参数放在后面。
【规则6-1-4】如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来
传递,这样可以省去临时对象的构造和析构过程,从而提高效率。
【规则6-2-1】不要省略返回值的类型。C 语言中,凡不加类型说明的函数,一律自动按整型处理。
【规则6-2-2】如果函数返回值是一个对象,要考虑return 语句的效率。return String(s1 + s2),编译器直接把临时对象创建并初始化在外部存储单元中,省去了拷贝和析构的化费
【规则6-5-2】在函数的入口处,使用断言检查参数的有效性(合法性)。断言assert 是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况
【规则7-3-1】指针p 被free 以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把p 设置为NULL,会让人误以为p 是个合法的指针。
【规则8-1-3】 当心隐式类型转换导致重载函数产生二义性:
# include <iostream.h>
void output( int x); // 函数声明
void output( float x); // 函数声明
void output( int x)
{
cout << " output int " << x << endl ;
}
void output( float x)
{
cout << " output float " << x << endl ;
}
void main(void)
{
int x = 1;
float y = 1.0;
output(x); // output int 1
output(y); // output float 1
output(1); // output int 1
/ / output(0.5); // error! ambiguous call, 因为自动类型转换
output(int(0.5)); // output int 0
output(float(0.5)); // output float 0.5
}
【规则8-2-1】成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。

【规则8-5-1】对于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型)。如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。
【规则9-5-1】现将a 赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。这将造成三个错误:一是b.m_data 原有的内存没被释放,造成内存泄露;二是b.m_data 和a.m_data 指向同一块内存,a 或b 任何一方变动都会影响另一方;三是在对象被析构时,m_data 被释放了两次。
【规则9-5-2】拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用:
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成 c(a);
c = b; // 调用了赋值函数
【规则9-8-1】基类与派生类的析构函数应该为虚(即加virtual 关键字);在编写派生类的赋值函数时,注意不要忘记对基类的数据成员重新赋值
【规则11-1-1用const 修饰函数的返回值:
(1)如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
(2)函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。
a = b = c; // 正常的链式赋值
(a = b) = c; // 不正常的链式赋值,但合法
如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动, 语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: