c++编程之const

const —— 一旦赋值便不能被修改的只读变量

1:常量与const
     const有数据类型,而常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查。常量的值在编译时已知,而且不需要分配存储;而const需要分配内存

2、const可修饰基本数据类型、指针、类、传递参数、函数

const修饰数据类型与指针

char* const a0; //指针是const类型
char const *a0; //指向的数据是const
const char *a0; //指向的数据是const

原则如下: const修饰的是它左侧的表示类型,如果const在最左侧,则修饰其右侧的表示类型

const修饰类

const对象的成员是不能修改的const成员函数不可以修改对象的数据不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。

const传递参数/返回值

将函数传入参数声明为const,禁止函数对其进行修改,在多线程的场景下这是必要的。const返回值可以阻止用户修改返回值,返回值也要相应的付给一个常量或常指针。

const函数

const成员函数不可以修改对象的数据不管对象是否具有const性质,做到多对象成员的保护


const与常量的使用:

1)提醒编程者,某些值是常量,或该值在程序运行期间是不变的,防止程序员误修改。

2)在多人多模块开发中,头文件引用复杂,模块之间可能会冲突。#define可以重复定义,而const不可以重复定义。如下: 

#define PI 3.14;
#define PI 3.1415926;
int const a1 = 10;
//int const a1 = 11;

3)#define宏不支持类型,无法进行类型检测

4)#define宏无法实现const的一些功能。如函数传递const参数,如c++类机制中的const成员的访问性控制。


const变量的存储

int main()  
{  
    const int con_var1 = 3;  
    int * b = (int *)&con_var1;  
    *b  = 5;  
    std::cout <<con_var1 << " "<<*b ;  //c语言使用printf打印
    return 0;  
}
在c++编译器中,输出为3;在c编译器中,输出为5

这段代码只是为了分析const存储在哪里,对一个const定义的变量使用指针强制访问是非常无聊的。

在c中,const是存储在栈中的,他会随着内存访问改变而改变。在c++中,没有存储在栈中,而是存储在某一个特定表中,在使用时被装入内存区(栈中),因此即使使用*b = 5把栈区的存储改变,在cout输出时,仍然从特定表中取数据而不是从栈区存储中取数据。

再看一个例子

        int v = 3;
	const int *ptr_cvalue = &v;
	cout << v;
	cout << *ptr_cvalue;
	v = 5;
	cout << v;
	cout << *ptr_cvalue;
输出为3,3,5,5  这个实验的目的是为了再次说明,const机制并没有在运行期有任何行为,只是编译期的行为。


假如把const定义为全局变量呢?

int const s1 = 10;
int main()
{
	int *p2 = (int *)&s1;
	*p2 = 100;
	cout << s1 << endl;

}
编译OK,运行会报错。全局变量定义的const存储在数据区,且受保护,*p2 = 100这条语句的执行会引起错误


综上:

1、 在c语言中,const修饰的数据存储在栈区(全局的存储在数据区) ;c++中存储在特定表中,栈区的只是一个类似的copy,被const修饰的属性在表中不会被修改,且调用时从表中区而不是从数据存储区读取。

2、 使用const的目的是不被修改,因此在c语言中,不要使用指针强转去获取const修饰变量

3、 const是在编译的时候被实现的一种数据保护机制,在执行中遇到问题是正常的~~~







猜你喜欢

转载自blog.csdn.net/ly601579033/article/details/52401284