欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

const限定符的一些使用区别

程序员文章站 2022-07-09 21:42:25
...

const限定符的一些使用区别

注意事项

const对象必须初始化
const对象仅在文件内有效,多个文件同名的const变量,实际上是在不同文件里分别定义了独立的变量。
在头文件中声明的const对象,与宏定义#define是一样的用法,只要包含该头文件,就可以直接使用该对象
需要注意的是,如果实现文件里重新定义了一个同名文件,那么该块内重新定义的对象有效,如下:

//test.h
const int a = 5;

//main.cpp
#include <iostream>
using namespace std;
int main()
{
	cout << a << endl;
	int a = 6;
	a = 7;
	cout << a << endl;
}

输出结果是5和7,第一个打印的是头文件中的 a 的值,因为在预编译的时候已经把该声明编译到该文件中了,第二个打印的是重新声明的变量 a 的值。
如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字, 如下:

//test.cpp
extern const int b = 8;

//main.cpp
#include <iostream>
extern const int b; 
using namespace std;
int main()
{
	cout << a << endl;
	int a = 6;
	a = 7;
	cout << a << endl;
	cout << b << ensl;
}

b的输出结果是8,需要注意的是:

//main.cpp
#include <iostream>
extern int b;

如上述这样声明程序不会报错,同样可以输出b的值8。但是,由于没有const限定符,编译器会允许对b进行赋值,一旦对b进行了赋值,编译器不报错,但运行时程序会崩溃。

引用

有下面这样一种情况,我们声明了一个变量,这个变量随着程序运行是会发生变化的,我们在另一个地方希望使用这个值,但是不能改变这个值,就可以创建一个这个变量的常量引用

	double dVal = 3.14;
	const double &ri = dVal;

这样,dVal的值变化时,ri跟着变化,但是不允许对ri进行赋值;

	double dVal = 3.14;
	const int &ri = dVal;

上面这样也可以,但会产生一个临时变量来进行类型转换

const int temp = dVal;
const int &ri = temp;

只是,发生类型转换时,必须声明的是一个常量引用,如果是下面这样

	double dVal = 3.14;
	int &ri = dVal;

编译器就会报错,因为这种发生了类型转换的引用,实际上是把引用绑定在了临时变量上,c++语言是不允许的。

指针

指向常量的指针(指针常量)

这种情况与引用的用法是一样的,指向常量的指针也没有规定其所指的对象必须是一个常量。所以指向常量的指针仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不呢个通过其他途径改变。

// 1
double pi = 3.14;
double *ptr = &pi;	//正确
// 2
const double pi = 3.14;
double *ptr = &pi;	//错误,必须定义成指针常量,同样,引用也是如此
// 3
const double pi = 3.14;
const double *ptr = &pi;		//正确,指针常量

第1种情况,可以通过指针进行赋值操作如:

*ptr = 6.66;	//正确,同时pi的值也被改变

但是第三种情况就不能进行赋值,也就是说定义一个指针常量,指向的内存空间中要放一个常量,可以通过指针来调用这个值,却不能改变它,如果改成如下,更直观些:

// 4
double pi = 3.14;
const double *ptr = &pi;		//正确

第3种情况中,我们声明了一个常量,那么再声明一个指针时,就只能声明一个指针常量。如第4种情况,pi的值可以改变,取值 *p时,值同样会跟着改变,但是不能对 *p进行赋值。
另外,将const double 写成double const也可以,两者等价,仅是书写风格问题,不再讨论。

另一种情况就是const指针(常量指针)

指针是对象而引用不是,因此就像其他对象类型一样允许把指针本身定义为常量。常量指针必须初始化,而一旦初始化完成,则他的值就不能再变了。我们拿第1种情况改一下举例:

// 5
	double pi = 3.14;
    double *ptr = &pi;	//正确
    cout << *ptr << endl;
    double dVal2 = 9.999;
    ptr = &dVal2;	//正确
    cout << *ptr << endl;

一般的指针是可以重复赋值的,也就是一个变量,但是加上const就会发生改变:

// 6
	double pi = 3.14;
    double *const ptr = &pi;	//正确
    cout << *ptr << endl;
    double dVal2 = 9.999;
    ptr = &dVal2;	//错误, 指针不能被改变
    cout << *ptr << endl;

声明函数

在函数声明中的用法是一样的

const int fun1(int *ptr);	//返回值应该是一个常量而不是变量,通常返回的值都是常量,
							//两种常见的返回非const对象情形是,重载赋值运算符以及重载与cout一起使用的<<运算符。不过多讨论
int fun2(const int *ptr);	//传递一个参数进来,但是在这个函数内,该参数不能被改变

另外会看到类似如下这样的函数

void func2()const;	//通常不能这样声明函数

这是在类中才能这样声明,意思是这个成员函数里,不能改变成员变量;

class val
{
    int m;
public:
    void fun3()const;	//正确
};

void val::fun3()const
{
    m = 3;	//报错,m 是成员变量,这里不能被改变
}
相关标签: const