const限定符的一些使用区别

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 是成员变量,这里不能被改变
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值