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

「C++」条款02 & 03:#define & const

2013-06-08 10:45 197 查看
关于 #define

#define ASPECT_RATIO 1.63
const int AspectRatio 1.63;


如果我们的代码中用到了 ASPECT_RATIO 宏,编译器只会简单粗暴的把其替换为 1.63,如果后期我们调试的过程中莫名其妙的遇到了 1.63 可能追踪半天都不会清楚问题发生在什么地方。另外每次的替换,相当于扩大了代码体积,违背了重用的原则。再来看看 const 下定义的 AspectRatio,完全避免了上面几种情况的发生。

#define 往往也会在我们意料之外出错,如下面的情况:

#define MAX_NUM ((a) > (b) ? (a) : (b))

int a = 5, b = 0;
MAX_NUM(++a, b);
MAX_NUM(++a, b + 10);


第一个 MAX_NUM 宏 ++a 执行了 2 次,而第二个只执行了 1 次,这显然不是我们想要达到的效果,下次还是老老实实写成函数吧。

static const

以前用类封装函数的时候,想着定义一个 const 常量,而且控制在类的作用域里面。下面的代码展示了几种可行的情况:

class GamePlayer {
private:
static const int NumTurns = 5;
int scores[NumTurns];
...
};

class GamePlayer {
enum { NumTurns = 5 };
int scores[NumTurns];
...
};


const 的几种情况

关于 const 的几种定义就不在叙述了,下面主要针对 const 的几种关键用法:

class BigNum { };
const BigNum operator * (const BigNum& lhs, const BigNum& rhs);


这里不禁会有疑惑,为什么我们没有 return by reference 却加了一个 const 的在函数前面呢?想想如下情况:

BigNum a, b, c;
if (a * b = c) {
...
}


如果有人粗心的把 == 写成 = 就会引发程序的逻辑错误,如果设置返回为 const 的话,编译器就会帮助我们检测出来这些低级的逻辑问题。

再考虑关于“const 成员函数”的用法,也是 C++ const 几种经典案例之一:

class CTextBlock {
public:
const char& operator[] (size_t position) const {
...
...
return text[position];
}
char& operator[] (size_t position) {
...
...
return text[position];
}
private:
char* text;
};

// 此时调用 const 成员函数
void print(const CTextBlock& ctb) {
cout << ctb[0];
}
// 此时调用 non-const 成员函数
void print(CTextBlock& tb) {
cout << tb[0];
}


也许你会发现两个成员函数执行的操作会是相同的,这样无疑重复了很多代码量,书中给出了下面的一种做法,让 non-const 调用 const 成员函数:

const char& operator[] (size_t position) const {
...
...
return text[position];
}
char& operator[] (size_t position) {
...
...
...
return const_cast<char&>                    // 去掉 const 属性
(static_cast<const CTextBlock&>     // 为 *this 加上 const
(*this)[position]);             // 调用 const op[]
}


最后还有一个要点就是,对于编译器来说,const 成员函数里面是不允许修改类成员变量的,这有时候会给我们带来麻烦,但是可以通过关键字 mutable 来解决,例如:mutable size_t length;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: