首先明确 : const量不可变, * 代表被指的数据,名字代表指针地址
char gre[] = "Hello"; //前面讲过不如 const std::string ptr = "Hello" char *ptr = gre; //这是只是演示 const char* ptr = gre; //常数据,非常指针 char* const ptr = gre; //常指针,非常数据 const char* const ptr = gre;//常指针,常数据 //补充: const char* ptr = "hello"; //若是指针只能指向字符常量 const char* const ptr = "hello"; //ok! //but char* const ptr = "hello"; //报错 char* ptr = "hello";//报错,指针要指向一个地址或引用,不能指向字符或字符串 //指针可以为0;int* p = 0;但不能给其赋值,int* p = 1;//错误!说明: const出现在 * 左边,表示被指物是常量;出现在 * 右边,表示指针自身是常量;出现在 * 两边,表示被指物和指针两者都是常量。
下面两种写法不一样,但意义相同
int const * ptr; const int* ptr; //都是非常指针,常数据☆ 常(const)成员函数不能给非静态成员变量赋值,除非用mutable 例:
class Class{ char *pText; std::size_t textLength; bool isValid; public: std::size_t length() const; }; std::size_t length() const { if(!isValid){ textLength = std::strlen(pText);//错误!在const成员函数内 isValid = true; //不能给textLength、isValid赋值 } return textLength; }而加上 mutable 后:
class Class{ char *pText; mutable std::size_t textLength; //这些成员变量总是可能被更改 mutable bool isValid; public: std::size_t length() const; }; std::size_t length() const { if(!isValid){ textLength = std::strlen(pText);//正确!在const成员函数内 isValid = true; //可以给textLength、isValid赋值 } return textLength; }但mutable不能解决所有问题。 在常成员函数内不能调用 non-const 成员函数,必须先经过 const_cast 将 const 属性去掉,然后才能安全调用。但在 non-const 成员函数中调用一个 const 并不会带来风险。更详细的内容将在后面的条款中介绍。
最后请记住:
将某些东西声明为 const 可以帮助编译器侦测出错误用法。const 可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。编译器强制实施 bitwise constness ,但你编写程序是应该使用“概念上的常量性”(conceptual constness)。当 const 和 non-const 成员函数有着实质等价的实现时,令 non-const 版本调用 const 版本可避免代码重复。