条款02 尽量以const,enum,inline替换#define
相比#define宏定义具有以下优点:
- const关键字可以定义常量,具有类型信息,编译器可以对其进行类型检查和优化。相比之下,#define宏定义只是简单的文本替换,没有类型信息,可能导致编译错误或者不期望的行为。
- enum关键字可以定义枚举类型,提供了一种更安全和可读性更高的方式来表示一组相关的常量。相比之下,#define宏定义没有类型检查和作用域限制,可能会导致命名冲突和可读性问题。
- inline关键字可以定义内联函数,可以将函数体嵌入到调用处,避免函数调用的开销。相比之下,#define宏定义只是简单的文本替换,没有类型信息,可能会导致编译错误或者不期望的行为。
因此,使用const、enum和inline可以提供更好的类型安全性和可维护性,建议尽量替换掉#define宏定义。
#define PI 3.14159
const double k = 3.14159;
enum { e = 3.14159 };
inline double get_pi() { return 3.14159; }
在这个示例中,使用const关键字定义常量k,使用enum关键字定义枚举类型e,使用inline关键字定义内联函数get_pi。这些关键字都具有类型信息,编译器可以对其进行类型检查和优化,避免了使用#define宏定义可能带来的问题。
条款3 尽可能使用const
const 他允许指定一个约束, 可以获得编译器的相助,确保这条约束不被违反。
char greeting[] = "hello";
char *p = greeting; //non-const pointer, non-const data
const char * p = greeting; //non-const pointer, const data
char *const p = greeting; //const pointer, non-const data
const char * const p = greeting; // const pointer, const data
- const char * p = greeting; //non-const pointer, const data
不能使用p 去改变greeting的值, greeting可以自己改变自己的值。 - char *const p = greeting; //const pointer, non-const data
p 只能指向 greeting, 不能在指向其它数据 如 p = tmp; - const char * const p = greeting; // const pointer, const data
p 不能改变指向,也不能改变指向的值
const 出现在星号左边,表示被指物为常量,如果是右边,表示指针自身是常量。如果是星号两边,表示被指物和指针都是常量
void f1(const Widget * pw);
void f2(char Widget *pw);
f1和f2 都一样, 表示f1获取一个指针, 指向一个常量(不变)Widget对象。
const 成员函数
const作用于成员函数, 目的是:
1.比较容易理解, 哪些函数可以改动对象内容, 哪些函数不可以改动成员函数内容
2.操作const对象称为可能。
3.const成员函数不可以更改对象内任何non-static 成员变量。
如果在静态成员函数中,使用非静态成员变量, 则可以把成员变量声明为mutable(可变的)
class CTextBlock{
public:
size_t length() const;
private:
char *pText;
mutable size_t textLength;
mutable bool lengthIsValid;
};
size_t CTextBlock::length() const {
if(!lengthIsValid){
textLength = strlen(pText);
lengthIsValid = true;
}
return textLength;
}
注意:
1.const可帮助编译器侦测出错误用法, const可用于任何作用域的对象、函数、函数返回类型、成员函数等。
2.当const 和non-const成员函数有实质等价实现时,令non-const版本调用const版本,可避免代码重复。