C++-const

253 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天点击查看活动详情

const作用

修饰变量

被定义后每次取值是从寄存器中取 直接将对应的值替换到变量的位置 被const修饰的变量,会在编译期间将对应的变量,直接替换为该变量的值 与之相对的是volatile。被这个关键字修饰的话,代表告诉了编译器,这个变量时随时可能被修改的。防止编译器优化,每次读取该值时,从内存中读取。而不是从编译器优化的寄存器中读取

const类成员函数

声明一个const类型的类成员函数,只需要在成员函数参数列表后加上关键字const 非const定义对象可以调用const与非const函数 const定义对象只能调用const修饰的函数,不能调用非const函数,因为他有可能对对象进行修改。 只有被声明为const的成员函数才能被一个const类对象调用


class A{
public:
   void fun1 const;
   void fun const
   {
   }
};
void A::fun1() const
{
}

const重载

如果是类的成员函数就运行重载

class A
{
public:
	void fun()
	{
		cout << "fun1";
	}
	 void fun () const
	{
		cout << "fun2";
	}
};
void main()
{
	A const a;//只有const类型对象才能调用const类函数 所以运行重载
	a.fun();//fun2
	A b;
	b.fun();//fun1
}

如果不是就不允许

void fun()
{
	cout << "fun1";
}
const void fun()
{
	cout << "fun2";
}

关于能否修改const值

全局const当声明extern或者对变量取地址时,编译器会分配存储地址,变量存储在只读数据段 但是其他情况下是不会分配内存 会存在符号表中

不能修改的情况

const int a = 10;//此时并没有给a分配内存 只是将a放在符号表中
int *p = (int*)(&a)//只有在调用&a的时候才会临时在栈区分配一个临时空间temp,temp空间的值是10.之后将临时空间的地址赋值给指针p
*p = 100;
cout <<p<<endl;//0x00FF00CC
cout<<&a<<endl;//0x00FF00CC
cout << *p << endl;//从内存0x00FF00CC中取值,等于100.
cout << a << endl;//从符号表中取值,等于10.

我们会发现p和a的地址其实是一样的 但是他们的内容不一样 如果单从p来看const int a的值貌似被改变了 实际上a并没有被改变 a在这一段的作用范围内就是10 变量a=10,a放在了符号表里面,这个值永远不会变。当取a的值的时候,就从符号表里面取,永远是10. 他不是从地址去取这个值了 而是直接从符号表 所以这个地址里的值改成什么都没关系

也可以理解为 最开始const int a = 10将a=10放进符号表中 (int*)(&a)后创建了一个临时空间Ox010100(随便写的)存储10这个值 并不是存储a 让p指针获取了这个地址 在这个语句之后 a和p没有任何关系了 a照样是存储在符号表中 p存储了一个存放着值为10的地址

可以修改的情况

    const int& ref = 10; //相当于int temp = 10;   const int& ref = temp;
// 此时应该不const修饰的就不是ref了 是&ref 也就是这个别名不能更改
    int* p = (int*)&ref;
    *p = 10000;
    cout << ref << endl; //10000
    /*因为你会发现*/
    //const int& ref = 10;
    //int b = 20;
    //reg = b;//就行不通会报错了