对C++中const的总结

来源:互联网 发布:数据库体育信息管理 编辑:程序博客网 时间:2024/06/07 08:41
1、C++中const的实现机制
简单的说,const在C语言中表示只读变量,在C++中表示常量。

void CFun(){
const int num = 10;
int *ptr = (int *)(&num);
*ptr = 20;
printf("num = %d, *ptr = %d\n", num, *ptr);
}

输出为 num = 20, *ptr = 20;

C语言中const表示只读的变量,那么内存中就有存储它的内存空间,并且可以通过指针间接改变该内存空间的值。
当通过ptr改变该内存中的值后,再获取num的值的时候会访问该空间,得到的是被改变后的值。

const int num = 10;
int *ptr = const_cast<int *>(&num);
*ptr = 20;

cout << "num = " << num << ", *ptr = " << *ptr << endl;


输出 num = 10, *ptr = 20
C++把const看做常量,编译器会使用常数直接替换掉对num的引用,并不会去访问num的内存地址去取数据
cout << num; 理解成 cout << 10;

struct Test {
int num;
char ch;
Test(){
num = 10;
ch = 'a';
}
};
const struct Test test;
int *ptr1 = (int *)(&test.num);
ptr1 = 20;

cout << "struct test.num = " << test.num << ", *ptr1 = " << *ptr1 << endl;


输出:struct test.num = 20, *ptr1 = 20
C++中只是对内置数据类型做常量替换,对于结构体这种非内置类型则不会,因此必须要访问内存去取数据,
而访问内存取到的必然是被指针ptr1改变后的值,因此会造成和const int不一样的结果。

2、const和#define区别
1>编译器处理方式不同
#define宏在预处理阶段展开
const常量是编译运行阶段使用
2>类型和安全检查不同
#define宏没有类型,不做类型检查,仅仅是展开
const常量有具体的类型,在编译阶段执行类型检查
3>存储方式不同
#define宏仅仅是展开,有多少地方使用就展开多少次,不会分配内存
const常量会在内存中分配
4>const节省空间,避免不必要的内存分配
#define PI 3.14159
const double Pi = 3.14159; 此时并未将Pi放入ROM中
double i = Pi; 此时为Pi分配内存,以后不再分配
double I = PI; 编译期间进行替换,分配内存
double j = Pi; Pi不再分配内存
double J = PI; 再次进行替换,又一次分配内存
5>提高效率
编译器通常不为普通const常量分配存储空间,而是将他们保存在符号表中,使它成为一个编译期间的常量,没有存储和读内存的操作,它的效率也很高


3、const的重载
Class A{
int fun();
int fun() const;
};
A类中fun()发生了重载。只有A类的const对象才能调用const版本的fun(),而非const对象可以调用任意一种,但通常非const对象调用非const版本。
分析:函数名相同而形参列表不同的函数称为重载。在类中,由于隐含this指针,
const版本的fun()使得作为形参的this指针类型变成指向const对象的指针。
非const版本的fun()使得作为形参的this指针就是正常版本的指针。此处是发生重载的本质。
this指针是一个const指针,地址不能改,但能改变其指向的对象或者变量)

0 0
原创粉丝点击