const关键字用于通知编译器,不能修改某个变量的值。该关键字的使用应该以最小特权原则为指导。
定义一般常量:直接在变量类型前或后加上关键字const
int main(){ int const a = 10;//定义int常量a=10 const int b = 100; // 定义int常量b=100 const double c = 1000; //定义double常量c=1000 cout << a << endl;//输出a cout << b << endl;//输出b cout << c << endl; return 0; } |
程序正常运行 |
const与指针
const与指针组合一共有3种,指向常量的常量指针,指向常量的非常量指针,指向非常量的常量指针。至于指向非常量的非常量指针,也就是一般的指针,我们不用管它。
指向常量的常量指针:无法通过该指针修改对应数据,无法修改该指针指向另一个常量。
int main(){ const char *const p = "hello world";//p是一个指向字符串常量的常量指针 cout << p << endl; return 0; } |
程序输出hello world |
试图通过该指针修改对应数据:会导致编译错误
int main(){ char str[] = "hello world"; const char *const p = str; //p是一个指向常量的常量指针
p[0] = '?'; //编译错误,试图通过p修改对应的数据
cout << p << endl; return 0; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|9|error: assignment of read-only location '*(const char*)p'| |
试图修改该指针指向另一个常量:同样会导致编译错误。
int main(){ char str[] = "hello world"; const char *const p = str; //p是一个指向常量的常量指针
p = "hello china";//试图修改指针p,指向另一个常量 cout << p << endl; return 0; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|8|error: assignment of read-only variable 'p'| |
指向常量的非常量指针:无法通过该指针修改对应数据,但可以改变该指针指向另一个常量。
int main(){ char str[] = "hello world"; const char *p = str; //p是一个指向常量的非常量指针 cout << p << endl; return 0; } |
程序正常运行输出 hello world |
试图痛改该指针修改对应的数据:将会导致编译错误。
int main(){ char str[] = "hello world"; const char *p = str; //p是一个指向常量的非常量指针 p[0] = '?';//试图通过指针p修改str的值,导致编译错误 cout << p << endl; return 0; } |
G:\users\lichanglou\CodeBlocks\C++默认实参的学习\main.cpp|8|error: assignment of read-only location '* p'| |
改变该指针指向另一个常量:程序正常运行。
int main(){ char str[] = "hello world"; const char *p = str; //p是一个指向常量的非常量指针 p = "hello china";//p指向另一个常量,程序正常运行。 cout << p << endl; return 0; } |
输出 hello china |
指向非常量的常量指针:可以通过该指针修改对应的数据,无法修改该指针指向另一个常量。
int main(){ char str[] = "hello world"; char *const p = str; //p是一个指向非常量的常量指针。 cout << p << endl; return 0; } |
程序输出 hello world |
通过该指针修改对应的数据:可以正常运行
int main(){ char str[] = "hello world"; char *const p = str; //p是一个指向非常量的常量指针。 for(int i = 0; i < 10; i++ ) p[i] = '?'; //通过指针p将对应的数据修改成'?' cout << p << endl; return 0; } |
程序输出:??????????d |
试图修改该指针指向另一个常量:编译错误
int main(){ char str[] = "hello world"; char *const p = str; //p是一个指向非常量的常量指针。 p = "hello china";//试图修改p指向另一个常量 cout << p << endl; return 0; } |
G:\users\lichanglou\CodeBlocks\C++引用学习\main.cpp|9|error: assignment of read-only variable 'p'| |
const与类
cosnt成员数据:类中的const成员数据必须在构造函数的初始化列表中进行初始化。const指针成员也要初始化。
class A{ public: A():a(0){}; //常量a在构造函数初始化列表中进行初始化。程序正常编译 private: const int a;//常量a }; |
class A{ public: A(){};//常量a未在构造函数初始化列表中初始化,编译错误 private: const int a;//常量a }; |
G:\users\lichanglou\CodeBlocks\C++引用学习\main.cpp|7|error: uninitialized const member in 'const int' [-fpermissive]| |
const数据成员不能被成员函数修改,但是const同指针结合作为数据成员时,按照前面介绍的规则。
class A{ public: A(int):a(0){};//常量a在构造函数初始化列表中初始化 void add(){a++;} //试图修改常量a的值。 private: const int a; }; |
G:\users\lichanglou\CodeBlocks\C++引用学习\main.cpp|8|error: increment of read-only member 'A::a'| |
class A{ public: A():p("hello world"){};
void aaaa(){ p = "hello china";//修改了p指向另一个字符串,是可以的 } const char* p; }; |
const成员函数:必须在类成员函数的声明和定义中都加上关键字,因为在类中,同一个函数和它的cosnt函数会被认为是对它的重载。
class A{ public: A(){}; int add(int, int);//一般成员函数 int add(int, int)const;//const成员函数 }; int A::add(int a, int b){//一般成员函数的实现 return a+b; } int A::add(int a, int b)const{//const成员函数的实现 return a+b; } |
const成员函数不允许修改成员变量:
class A{ public: A():a(10){};
void add()const{ a++;//试图修改成员变量,编译错误 } int a; }; |
G:\users\lichanglou\CodeBlocks\C++引用学习\main.cpp|10|error: increment of member 'A::a' in read-only object| |
const成员函数只允许调用const成员函数:
class A{ public: A():a(10){};
void addd()const{ add();//调用非const函数,编译错误 } void add(){ a++; } int a; }; |
const对象:const对象只能调用const成员函数。
class A{ public: A():a(10){};
void add(){//非const函数 a++; } int a; };
int main(){ const A a; a.add();//试图调用非const函数,编译错误。 cout << a.a << endl; return 0; } |
总结
const同指针相结合还是很麻烦的。至于静态常量后面在说。