C++中什么是常量
常量:在程序运行期间不能发生改变的变量,常量不限制类型,但是在定义之后值不可修改
c++中定义常量有两种方法
- 使用宏定义#define预处理器(来自C语言)
#define DEF_WINDOW_WIDTH 720 - 使用const关键字
const int DEF_WINDOW_WIDTH 720;
const的4种用法
- 修饰变量,将变量定义成常量
- 修饰引用,一般用于对函数的形参(常引用),避免了函数内对值的更改
- 修饰函数,表示修饰函数的返回值、成员函数后面加const说明函数内不会修改成员变量
- 修饰指针,分为两种(指针自身是常量和指针指向了一个常量)
const修饰变量
#include<iostream>
class Test_Class {
private:
const int a = 9;
int b =10;
const int c;//1.没有赋值,构造函数需要对其进行初始化
int d;
public:
Test_Class():c(0){//构造函数初始化常量c的值
std::cout << __FUNCTION__ << " b=" << b << " a="<<a << std::endl;
b++;
//a++;//2.错误 常量无法修改
};
int GetValueA(){
std::cout << __FUNCTION__ << std::endl;
return a;
};
int GetValueBConst() const{
std::cout << __FUNCTION__ << std::endl;
return b;
};
};
int main()
{
Test_Class t_class;//普通对象,可以调用全部成员函数
const Test_Class c_t_class;//常量对象
std::cout << t_class.GetValueA() << std::endl;
//std::cout << c_t_class.GetValueA() << std::endl;//3.错误,常量对象,不可以调用非常成员函数
std::cout << c_t_class.GetValueBConst() << std::endl;
return 0;
}
const修饰引用
引用只是个别名
- 常量引用,无法进行修改
void Func(){
char ch = 'a';
const char& c_ch = ch;
char& d_ch = ch;
std::cout << ch << std::endl;//a
std::cout << c_ch << std::endl;//a
ch = 's';
std::cout << ch << std::endl;//s
std::cout << c_ch << std::endl;//s
//c_ch = 't';错误
d_ch = 't';
std::cout << ch << std::endl; //t
std::cout << c_ch << std::endl; //t
}
- const修饰函数的引用形参,与前一个类似,允许输入参数为const修饰的值(常量引用或常量)或右值
void func(int& a){
std::cout << a << std::endl;
}
void func_const(const int& a){
std::cout << a << std::endl;
//a++;//错误,const 不允许修改形参
}
func(11);//错误
func_const(11);//正确
const修饰函数
- 函数声明末尾加const,说明该成员函数内不能修改成员变量。
#include<iostream>
class Test_Class {
private:
int a = 9;
public:
Test_Class() {
std::cout << __FUNCTION__ << " a=" << a << std::endl;
};
int GetValueA(){
std::cout << __FUNCTION__ << std::endl;
a++;
return a;
};
int GetValueBConst() const{
std::cout << __FUNCTION__ << std::endl;
//a++;//错误,常量函数不可修改成员变量
return a;
};
};
int main()
{
Test_Class t_class;
std::cout << t_class.GetValueA() << std::endl;
std::cout << t_class.GetValueBConst() << std::endl;
}
- 修饰函数的返回值,防止函数返回值被修改(归根其实是const修饰指针or引用)
#include<iostream>
const char* Const_TestFun(){
char* array = new char[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
return array;
}
char* TestFun(){
char* array = new char[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
return array;
}
int main(){
const char* s = Const_TestFun();
char* p = TestFun();
//*s = 'n';错误,不能修改返回值
cout << s << endl;
*p = 'n';
cout << p << endl;
}
const修饰指针
- 指针常量:就是指针本身是常量,进一步解释:指针的值(内存地址)是常量,不能改变,但内存地址对应的元素是可以通过指针改变的。(本质上是一个指针类型的常量)
int * const p
- 常量指针:就是指向常量的指针,进一步解释:定义时不需要对它进行初始化,指针指向了常量,它指向的值不能发生改变,但可以通过原有的声明来修改。(本质上是一个指针)
int const * p;
const int *;
仔细阅读以下例子
#include<iostream>
int main(){
int a = 10;
int b = 20;
int e = 40;
const int* d_ptr = &b; //常量指针
cout << "d_ptr:" << d_ptr << " " << *d_ptr << " " << b << endl;
//*d_ptr=20; 不能通过常量指针来修改变量的值
b = 30; //可以通过修改常量指针指向的对象值 来修改常量指针的值
d_ptr = &e; //同时常量指针可以指向任意其他地址
cout << "after d_ptr:" << d_ptr << " " << *d_ptr << " " << b << endl;
int* const ptr_c = &a; //指针常量
cout << "ptr_c:" << ptr_c << " " << *ptr_c << " " << a << endl;
//ptr_c=&e; 对于指针常量 不能修改其指向的地址
*ptr_c = 99; //但是可以通过指针来修改变量的值
cout << "after ptr_c:" << ptr_c << " " << *ptr_c << " " << a << endl;
return 0;
}