1、视C++为一个语言联邦
C++主要的次语言有四种:C、Object-Oriented C++、Template C++和STL。
2、尽量以const,enum,inline替换#define
(1) #define单纯常量,编译前需要预处理器,没有进入编译的符号表,出错信息不容易定位。
(2) #define 不能用于定义常量指针,对const取地址合法,对#define取地址不合法;没有作用域的限制,不能成为类的专属成员。
(3) #define 定义宏,括号问题,容易出错,应以inline代替。
补充:后在《c和指针》中看到一些 #define 不能用函数替换的情况,但是在C++中都不是问题:
(1) 函数的参数必须声明为一种特定的类型,所以只适合在类型合适的表达式上使用。如果用模板,函数也可以实现多种类型,C++模板有类型推导同样不需要进行显示表明。
(2) 宏的参数如果是一种类型,无法作为函数参数传递。
在C++中,可以用typeid(X).name()获知变量的类型,或者使用模板,在模板函数中定义此类型变量等。
3、尽可能使用const
(1) 将函数的返回值声明为const可以防止被当做左值被赋值。
(2)成员函数const有两种理解,bitwise constness和logical constness。前者主张const成员函数不更改对象之任何成员变量,也即不更改对象内的任何一个bit;后者主张const成员函数可以修改所处理的对象内的某些bits,但只有在客户端侦测不出的情况下。前者对象内指针所指之物发生变化亦可,后者要添加mutable来表示对象成员可以改变。
(3)“常量性转移”,令non-const版本调用const版本来避免代码重复。
4、确定对象被使用前已先被初始化
(1) 内置类型手工初始化;非内置类型构造函数初始化时利用初始化列表,使成员变量初始化发生在进入构造函数之前,此时调用的是拷贝构造函数,而非调用默认构造函数再进行拷贝赋值,这样可以提高效率。
(2) 成员变量初始化次序与声明次序相同。
(3)c++定义于不同编译单元内的non-local static对象的初始化次序没有明确定义,为此,以local static对象替换为non-local static对象。

本文深入探讨了C++编程中常被忽视的细节,包括如何将C++视为一个语言联邦,以及如何有效利用const、enum和inline替代#define。文章详细阐述了#define的局限性,比如无法用于定义常量指针、没有作用域限制等问题,并提供了在C++环境中更优的选择。此外,文章强调了使用const的重要性,解释了const成员函数的不同理解及其应用,并提出了“常量性转移”的概念以避免代码重复。最后,讨论了确保对象在使用前被正确初始化的方法,包括内置类型的手动初始化、非内置类型的构造函数初始化以及跨编译单元对象初始化的注意事项。
1373

被折叠的 条评论
为什么被折叠?



