Item4:Use const whenever possible--尽可能使用const
2009-03-14 22:51
417 查看
先说下const,它来自于英文constant,意为始终不一,忠实,不变的。在程序中用作修饰语。大体的意思也就是固定不变,但一定要分清楚不同场合中具体的用法。
const 可用来修饰global或namespace作用域中的常量,或修饰文件、函数、区块作用域被声明为static的对象。 此时被const修饰的常量或对象是不可被修改的,修改将发生编译错误。
最让人头痛的是当const修饰指针的时候,它可以表示指针本身,指针所指物,或两者都是const。
看下面例子:
char greeting[] = “hello”;
char* p = greeting; // non-const pointer,non-const data
const char* p = greeting; // non-const pointer,const data
// 被指物是常量,不能改变,不能执行如*p = ‘a’这类操作。
//但指针可以改变 如执行p++操作
char* cosnt p = greeting // const pointer,non-const data
//指针是常量,不能对指针进行改变,不能执行p++这类操作
//但能对指针所指的数据赋值,如*p = ‘a’
const char* const p = greeting // const pointer, const data
//指针,指针指向的物体都是常量 都不可改变
注意const char* p 和 char const * p实际上是同一类型。
STL迭代器系以指针为根据塑模出来的,所以迭代器的作用就像一个T* 指针。
看下面声明:
std::vector<int> vec;
…
const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const
*iter = 10; // 没问题,改变iter所指物
++iter; // 错误!!!!iter是个const指针
如果希望迭代器所指的东西不可被改动(希望STL模拟一个const T* 指针),你需要const_iterator。如下:
std::vector<int>::const_iterator cIter = vec.begin(); // cIter的作用像个const T*
*cIter = 10; // 错误!* cIter是const
++cIter; // 没问题,改变cIter
const 最具有威力的用法是面对函数声明时的应用。用const可以提高函数的健壮性。
推荐一下准则:
1、如果输入参数采用“指针传递”,那么加const可防止意外的改动该指针起到保护作用。
2、如果输入参数采用“值传递”,由于函数产生临时变量用于复制该参数,该输入函数本来就无需保护,所以不需要用const修饰。
3、对于非内部数据类型的参数而言,像void func(A a)这样的声明的函数效率会很低,为了提高效率,可将传入参数改为引用 void func(A &a),这样不用产生临时对象。但存在一个缺点,在函数func中任意对a的操作都可能改变它,此时需用const修饰。最终函数应为 void func(const A& a)。
4、令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性。
最后就是const函数,不会修改数据成员,也不能调用非const成员函数。这一类函数之所以重要,是基于两个原因。第一,他们使class接口比较容易被理解。这是因为,得知哪个函数可以改动对象内容而哪些函数不行 ,是很重要的。第二,它们使“操作const对象”成为可能,这对编写高效代码是个关键。
请记住:
1、将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
2、编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
3、当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
const 可用来修饰global或namespace作用域中的常量,或修饰文件、函数、区块作用域被声明为static的对象。 此时被const修饰的常量或对象是不可被修改的,修改将发生编译错误。
最让人头痛的是当const修饰指针的时候,它可以表示指针本身,指针所指物,或两者都是const。
看下面例子:
char greeting[] = “hello”;
char* p = greeting; // non-const pointer,non-const data
const char* p = greeting; // non-const pointer,const data
// 被指物是常量,不能改变,不能执行如*p = ‘a’这类操作。
//但指针可以改变 如执行p++操作
char* cosnt p = greeting // const pointer,non-const data
//指针是常量,不能对指针进行改变,不能执行p++这类操作
//但能对指针所指的数据赋值,如*p = ‘a’
const char* const p = greeting // const pointer, const data
//指针,指针指向的物体都是常量 都不可改变
注意const char* p 和 char const * p实际上是同一类型。
STL迭代器系以指针为根据塑模出来的,所以迭代器的作用就像一个T* 指针。
看下面声明:
std::vector<int> vec;
…
const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const
*iter = 10; // 没问题,改变iter所指物
++iter; // 错误!!!!iter是个const指针
如果希望迭代器所指的东西不可被改动(希望STL模拟一个const T* 指针),你需要const_iterator。如下:
std::vector<int>::const_iterator cIter = vec.begin(); // cIter的作用像个const T*
*cIter = 10; // 错误!* cIter是const
++cIter; // 没问题,改变cIter
const 最具有威力的用法是面对函数声明时的应用。用const可以提高函数的健壮性。
推荐一下准则:
1、如果输入参数采用“指针传递”,那么加const可防止意外的改动该指针起到保护作用。
2、如果输入参数采用“值传递”,由于函数产生临时变量用于复制该参数,该输入函数本来就无需保护,所以不需要用const修饰。
3、对于非内部数据类型的参数而言,像void func(A a)这样的声明的函数效率会很低,为了提高效率,可将传入参数改为引用 void func(A &a),这样不用产生临时对象。但存在一个缺点,在函数func中任意对a的操作都可能改变它,此时需用const修饰。最终函数应为 void func(const A& a)。
4、令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性。
最后就是const函数,不会修改数据成员,也不能调用非const成员函数。这一类函数之所以重要,是基于两个原因。第一,他们使class接口比较容易被理解。这是因为,得知哪个函数可以改动对象内容而哪些函数不行 ,是很重要的。第二,它们使“操作const对象”成为可能,这对编写高效代码是个关键。
请记住:
1、将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
2、编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
3、当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
相关文章推荐
- 条款03:尽可能使用const(Use const whenever possible.)
- 条款03:尽可能使用const(Use const whenever possible.)
- 条款03:尽可能使用const(Use const whenever possible.)
- 条款3:尽可能使用const(use const whenever possible)
- Item15 Use constexpr whenever possible
- Item 3: Use const whenever possible(Effective C++)
- <Effective Modern C++>Item 15: Use constexpr whenever possible.[constexpr 表达式]
- Item3: Use const whenever possible
- 《Effective C++》读书笔记之三 Item 3. Use const whenever possible
- Effective C++----3rd Edition, Item 3:尽可能使用const
- Item 1: 尽可能的使用属性代替可访问的数据成员(Always Use Properties Instead of Accessible Data Members)
- 重读经典-《Effective C++》Item3:尽可能使用const
- 《Effective C++》Item3:尽可能使用const
- 条款03 use const whenever possible
- Item 03:尽可能使用const
- 重读经典-《Effective C++》Item3:尽可能使用const
- Effective C++ 之 Item 3:尽可能使用 const
- 条款03:use const whenever possible
- Effective C++ Item 03-尽可能使用const
- Effective C++ Item 3 尽可能使用const