【C++修炼之路 第二章:类和对象】(补充):const 修饰对象与 const 修饰成员函数 及其之间的调用关系(权限的放大与缩小)

前言:

一个类的成员函数:会有隐含的 this 指针作为函数第一个参数,这个成员函数没有被 const 修饰时,this 指针的类型为 Date* const(const 修饰 this,this 不能被修改)

正文:由例子引入

例一:

有时候,定义对象可能会加一个 const 修饰:使 *this 不能被修改

void TestDate()
{
    const Date d1(2024, 4, 4);
}

此时 调用该对象的成员函数 Print:会出现报错,为什么??(自己编译一下可知)

 void Date::Print(); 
 {
     cout << _year << "/" <<  _month << "/" << _day << '\n';
 }
 void TestDate()
 {
     const Date d1(2024, 4, 4);
     d1.Print(); // 调用该对象的成员函数 Print
 }

这里的报错:涉及 const 权限放大的问题

d1.Print(); 是传递 &d1 ,类型为 const Date* :这个意思是,对象d1 的指针指向的内容不能被修改

而 Print函数参数为 Date* this

显然,权限被放大了

如何解决?把 函数的 this 也改成 const Date* (两两匹配上),但是由于 this指针 是隐含的,无法直接使用 const修饰,那 Print函数应该怎么调整?

解决办法:用 const 修饰成员函数

做法:因为没办法直接显式的修饰 *this ,则定性规定在成员函数 右边加上表示修饰 * this,本质是改变 this 的类型(const Date* this :const 修饰 * this) 同时,原来的 this 本身是 Date* const this : this指针是不能修改的 现在又加一个const 修饰,则变成:const Date* const this

修改后的函数变成:

void Date::Print() const;

再定义一个,非 const 修饰的对象,可见:非 const 可以调用 const修饰 的Print:即 权限可以缩小

void TestDate()
{
    // 再定义一个,非 const 可以调用 const 的Print:权限可以缩小
    Date d2(2024, 4, 4);
    d2.Print();
}

小结:函数添加了 const,有 const修饰的对象 和 无const 修饰的对象 都能调用,因此函数能写 const 就写,安全性增加(保护对象本身)

例二:

使用日期类中的 运算符重载函数 举个例子:这里仅仅讨论关于 const 的部分

// 运算符重载函数:无需理会内部的实现,关注 函数声明部分即可
bool Date::operator<(const Date& d)
{
	// .....
}
​
void TestDate()
{
	const Date d1(2024, 4, 4);
	Date d2(2024, 4, 4);
	​
		// 为什么下面第一条式子会报错,第二条式子补会报错?
	d1 < d2; // d1 是 *this, d2 是用函数参数 const Date& d 接收
	d2 < d1; // d2 是 *this, d1 是用函数参数 const Date& d 接收
}
 

运算符重载函数的第一个参数: this 指针为 Date const* 类型,第二个参数:const Date

第一条式子(d1 < d2;),d1 是 const修饰的,但是重载函数的 this 指针没有 const修饰,因此和上一个例子同理,权限放大了

修改调整:函数加上 const,使 this指针被 const 修饰

bool Date::operator<(const Date& d) const
{
     // .....
}

总结:

        如果对象本身不涉及修改对象(如 拷贝构造、赋值重载….等函数需要修改 对象,就不能加const了),则 函数都需要用 const 修饰(都加上)

思考题:

1、const对象可以调用非const成员函数吗?不可以,权限放大:const Date* 调用 Date*

2、非const对象可以调用const成员函数吗?可以,权限缩小:Date* 调用 const Date*

3、const成员函数内可以调用其它的非const成员函数吗?

        不可以,权限放大:const Date* 调用 Date*

4、非const成员函数内可以调用其它的const成员函数吗?

        可以,权限缩小:Date* 调用 const Date*

这几个问题都是围绕【const 的权限可以缩小和平移,就是不能放大】的核心解决问题

【问题】const 的对象(或函数)可以调用 const函数,那如何调用 非const的函数?

强制类型转换:const_cast<T&>(对象名).成员函数; (T为类型 名)

举例:

class A {
public:
	A() {  };
	void Print() const {
		cout << "Print" << '\n';
	}
private:
	int _a;
};

int main()
{
	const A a;  // a 使对象名,A 是类型名
	const_cast<A&>(a).Print();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值