const 和 volatile 在实例成员函数的应用

constvolatile 的使用范围几乎没有限制
实例成员函数的参数后面可以出现 constvolatile,它们都用于修饰函数隐含参数 this 指向的对象
实例函数对象的参数表后面出现 const 说明this 所指向的对象是不能修改的只读对象
但是可以修改this所指向对象的非只读类型的静态数据成员
实例函数成员参数表后出现constvolatileconst volatile ,如果这些实例函数对象隐含参数this的修饰词不同,则可视为重载函数
调用实例函数成员,编译器会将实参的类型同this的类型匹配,从而调用最适合的实例函数成员
可读/写的普通变量或者对象应该调用参数表后不带 const 或者 volatile的实例函数成员
const对象则应该调用参数表后 带 const 的实例函数成员
volatile对象应该调用参数表后带 volatile 的实例成员函数
注意,如果调用的时候不存在对应的实例函数成员,会报错


我们来看一个例子,这个例子都是匹配的调用对应的函数

#include<iostream>
using namespace std;
class A {
	int a;
	const int b;
public:
	int f() {
		cout << "f() " << endl;
		a++;
		//b++;  不可修改
		return a;
	}
	int f()volatile {
		cout << "volatile f()" << endl;
		a++;   // 可以修改本类实例成员数据成员 volatile int a
		//b++;
		return a;
	}
	int f() const volatile {
		cout << "f() const volatile " << endl;
		// a++; 也是错误的
		return a;
	}
	int f()const  {
		cout << "f() const " << endl;
		// a++ ;也是错误的
		return a;
	}
	A(int x) :b(x) {
		a = x;
	}
};
A w(3);  // 这是一个可写对象
const A x(6);  // 这是一个可读对象
volatile A y(6);  // 定义易变对象
const volatile A z(8); // 定义可读易变对象
int main() {
	w.f();
	x.f();
	y.f();
	z.f();
}

最后的结果如下:
在这里插入图片描述

我们来分析一下上面的四个函数成员 f(), 这四个函数成员为重载函数,它们的显示参数表没有定义任何形参,但是隐含形参this的类型各不相同,this用于指向当前函数得对象。


我们来深入思考一下,如果没有最完美得匹配,编译器会退而求其次调用次匹配的函数吗?
看下面的代码,我把 fun() const 和 fun() volatile 都注释,看看情况会怎么改变

#include<iostream>
using namespace std;
class A {
	int a;
	const int b;
public:
	int f() {
		cout << "f() " << endl;
		a++;
		//b++;  不可修改
		return a;
	}
	//int f()volatile {
	//	cout << "volatile f()" << endl;
	//	a++;   // 可以修改本类实例成员数据成员 volatile int a
	//	//b++;
	//	return a;
	//}
	int f() const volatile {
		cout << "f() const volatile " << endl;
		// a++; 也是错误的
		return a;
	}
	//int f()const  {
	//	cout << "f() const " << endl;
	//	// a++ ;也是错误的
	//	return a;
	//}
	A(int x) :b(x) {
		a = x;
	}
};
A w(3);  // 这是一个可写对象
const A x(6);  // 这是一个可读对象
volatile A y(6);  // 定义易变对象
const volatile A z(8); // 定义可读易变对象
int main() {
	w.f();
	x.f();
	y.f();
	z.f();
}

运行结果如下
在这里插入图片描述
我们看的出来,const A x(6)volatile A y(6) 由于找不到最合适的匹配函数,都调用了 f() const volatile


我们再来看一个代码,只注释掉 f() const volatile 函数 ,看看如何

#include<iostream>
using namespace std;
class A {
	int a;
	const int b;
public:
	int f() {
		cout << "f() " << endl;
		a++;
		//b++;  不可修改
		return a;
	}
	int f()volatile {
		cout << "volatile f()" << endl;
		a++;   // 可以修改本类实例成员数据成员 volatile int a
		//b++;
		return a;
	}
	//int f() const volatile {
	//	cout << "f() const volatile " << endl;
	//	// a++; 也是错误的
	//	return a;
	//}
	int f()const  {
		cout << "f() const " << endl;
		// a++ ;也是错误的
		return a;
	}
	A(int x) :b(x) {
		a = x;
	}
};
A w(3);  // 这是一个可写对象
const A x(6);  // 这是一个可读对象
volatile A y(6);  // 定义易变对象
const volatile A z(8); // 定义可读易变对象
int main() {
	w.f();
	x.f();
	y.f();
	z.f();
}

发现
在这里插入图片描述
报错原因
在这里插入图片描述


我们在刚刚的基础上再把 f() const 注释调用

#include<iostream>
using namespace std;
class A {
	int a;
	const int b;
public:
	int f() {
		cout << "f() " << endl;
		a++;
		//b++;  不可修改
		return a;
	}
	int f()volatile {
		cout << "volatile f()" << endl;
		a++;   // 可以修改本类实例成员数据成员 volatile int a
		//b++;
		return a;
	}
	//int f() const volatile {
	//	cout << "f() const volatile " << endl;
	//	// a++; 也是错误的
	//	return a;
	//}
	//int f()const  {
	//	cout << "f() const " << endl;
	//	// a++ ;也是错误的
	//	return a;
	//}
	A(int x) :b(x) {
		a = x;
	}
};
A w(3);  // 这是一个可写对象
const A x(6);  // 这是一个可读对象
volatile A y(6);  // 定义易变对象
const volatile A z(8); // 定义可读易变对象
int main() {
	w.f();
	x.f();
	y.f();
	z.f();
}

我们来看看报错如何
在这里插入图片描述
在这里插入图片描述


我们最后进行一个实验,只把 f() 函数注释掉,看看会发生什么

#include<iostream>
using namespace std;
class A {
	int a;
	const int b;
public:
	//int f() {
	//	cout << "f() " << endl;
	//	a++;
	//	//b++;  不可修改
	//	return a;
	//}
	int f()volatile {
		cout << "volatile f()" << endl;
		a++;   // 可以修改本类实例成员数据成员 volatile int a
		//b++;
		return a;
	}
	int f() const volatile {
		cout << "f() const volatile " << endl;
		// a++; 也是错误的
		return a;
	}
	int f()const  {
		cout << "f() const " << endl;
		// a++ ;也是错误的
		return a;
	}
	A(int x) :b(x) {
		a = x;
	}
};
A w(3);  // 这是一个可写对象
const A x(6);  // 这是一个可读对象
volatile A y(6);  // 定义易变对象
const volatile A z(8); // 定义可读易变对象
int main() {
	w.f();
	x.f();
	y.f();
	z.f();
}

发现报错如下
在这里插入图片描述


总结一下,总的一个优先级如下:
啥都没有 > constvolatile > const volatile
我来解释一下,如果一个对象不含 const 以及 volatile ,那么会优先调用不含constvolatile 的函数,如果没有,就去调用 f() const 或者 f() volatile 之一,这里如果两个都存在,编译器不知道调用哪一个,就会报错,如果 f() const 或者 f() volatile 都不存在,才调用f() const volatile
如果对象是 const 类型的也是同样的道理,先去找f() const ,找不到才调用 f() const volatile

且补充一个小点,constvolatile 不能出现在构造函数或析构函数的参数表后,因为构造或者析构一个实例对象的时候,对象必须是可以修改的,且必须处于稳定状态(volatile 说明是易变对象)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wniuniu_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值