当const方法是公共的并且非const方法受保护时,为什么C++不会转换为const?

Kia*_*ian 11 c++ const

我用两个get方法创建了一个类,一个是const,一个是非const.const方法是公共的,因此用户可以查询向量.非const方法受到保护,因此我可以使用它来修改我需要的数据.

但是,当我尝试使用该类并调用get方法时,编译器会抱怨非const方法受到保护.相反,我必须使用const_cast将对象强制转换为const,因此我可以使用public方法.

有办法解决这个问题吗?为什么编译器不会执行转换,因为有一个公共方法?如果我删除受保护的版本并且只保留const版本,它可以正常工作,因此它会在这种情况下进行转换.转换为const始终是安全的.它正在消除常量问题.

Jos*_*eld 7

成员访问控制是调用成员函数时发生的最后一件事.它发生在名称查找,模板参数推导,重载解析等之后.它最后完成的原因是因为决定更改成员的访问控制不应该突然改变客户端代码的执行.

想象一下在重载解析之前检查了访问权限,并且您在该库中使用了库和某个成员函数.然后,图书馆作者将该功能设为私有.突然,您的代码开始使用不同的重载,并以完全不同的方式运行.库作者可能打算任何使用该函数重载的人都应该停止使用它,但他们并不打算改变每个人的代码.但是,由于标准实际上已定义,因此您的代码现在开始使用私有成员时出错,而不是表现不同.

解决方案是简单地更改受保护成员函数的名称,以便不考虑它.


Joh*_*eek 5

编译器决定要调用的成员函数考虑可访问性。也就是说,受保护和私有函数仍然可见,即使它们不可访问

为什么?原因之一是,如果重载决议忽略了不可访问的函数,则可以通过更改其可访问性来更改调用的函数。按照目前的规则,你只能导致编译代码无法编译,或者导致当前无法编译的代码,或者改变一些不影响代码含义的东西。您不能更改访问说明符并静默地导致调用不同的函数。

作为一个人为的例子,这是一个非常糟糕的类接口:

public:
    // Returns the amount of change tendered for this transaction.
    MoneyAmount change() const;

private:
    // Account for a change of currency. Charges standard moneychanger's fee.
    MoneyAmount change(Currency toCurrency = Currency::USD);
Run Code Online (Sandbox Code Playgroud)

如果从重载解析中删除了不可访问的函数,客户端代码就可以change()很好地调用。如果稍后将第二个change(Currency)函数公之于众而删除第一个函数,该代码会突然以完全不同的目的默默地调用另一个函数。当前规则阻止访问说明符的更改更改编译程序的行为。