C++ 调用const/non const函数的const/non const对象

C++ 调用const/non const函数的const/non const对象,c++,C++,在此代码中: include<iostream> using namespace std; class A { public: A(){} //constructor void fun() { cout<<"in non-const fun"<<endl; } void fun() const { cout<<"in cons

在此代码中:

include<iostream>

using namespace std;

class A
{
    public:
    A(){}               //constructor

    void fun()
    {
        cout<<"in non-const fun"<<endl;
    }

    void fun() const
    {
        cout<<"in const fun"<<endl;
    }
};

int main()
{
    A obj;
    A c_obj;

    obj.fun()
    c_obj.fun();
    return 0;
}
包括
使用名称空间std;
甲级
{
公众:
一个(){}//构造函数
虚无乐趣()
{

cout假设我们有一个类
a
,与OP描述的类类似(即,具有相同成员函数的
const
和非
const
版本,分别命名为
a::fun()const
a::fun()

这两个版本之间的区别在于
A::fun()const
函数的规范是,它不会从逻辑上改变调用它的对象的状态,但允许
A::fun()
这样做

如果表达式/语句
some_object.fun()
调用
a::fun()const
,则它不会更改
某些_object
的逻辑状态(即未指定为
可变的
静态成员的值)(假设不存在未定义的行为)

类似地,如果表达式
some\u object.fun()
调用
A::fun()
(非
const
版本),则
some\u object
的状态可能会在逻辑上发生更改

现在,我们需要看看实现(aka编译器)在遇到形式为
some\u object.fun()
的表达式时应该做什么。因为有
A::fun()常量和
A::fun()
,所以有必要为实现应用一些标准来决定调用哪一个

第一种简单的情况是
某个对象
被声明为
const
(或者是
const
a
的引用)

此声明表达了程序员的意图,
some\u object
的逻辑状态不会更改。允许
fun()
的非
const
版本更改
some\u object
的状态,因此它决不是
some\u object.fun()的有效匹配项
-如果实现选择此选项,则必须发出诊断(除其他外,通常意味着代码将无法编译)。所有这一切都意味着
a::fun()const
是这种情况下唯一允许的选项

第二种情况是
某些对象
未声明为
常量

A some_object;
some_object.fun();
声明表达了程序员允许(或至少不允许)更改
某些对象的逻辑状态的意图。由于
A
既有
const
又有
const
版本的
fun()
有三种可能的选择(理论上)已写入标准中

  • 更喜欢调用
    A::fun()const
    而不是
    A::fun()
    (非
    const
    版本)。不更改允许更改的对象没有害处。但是,此选项还消除了非
    const
    函数
    A::fun()的任何情况
    将被调用。因此,允许一个类同时具有两个版本是没有意义的
  • 宁愿调用
    A::fun()
    而不是
    A::fun()常量
    。这种选择没有坏处,因为在允许更改时更改对象没有坏处
  • A::fun()
    A::fun()const
    视为同样好的候选者。这会给编译器带来歧义,因为有两个同样有效的备选方案,没有理由选择其中一个,因此再次需要进行诊断。至于选项(1),这也意味着在任何情况下都不会调用non-
    const
    函数,因此允许类同时具有两个版本是没有意义的
  • 上述选项(2)是标准所要求的。这意味着在定义的情况下,可以调用
    A::fun()
    A::fun()const
    (分别为非
    const
    const
    对象),并且选择中的不确定性最小


    使用两个选项(1)和(3),程序员没有必要同时提供
    A::fun()
    A::fun()const
    -或者标准甚至允许程序员提供两个版本-因为在任何情况下,当给定形式为
    some_object.fun()
    的语句或表达式时,都不会调用非
    const
    版本。要引入选项(1)或(3),需要标准中的一组附加子句,指定了函数的非代码> const < /> >版本。而C++标准化委员会对于包含晦涩复杂的规则(可能过分)是值得注意的。在这种情况下,它们似乎没有调用。

    因为非
    常量
    对象将调用函数的非
    常量
    版本(如果有)。您已经很好地描述了预期的行为。您在寻找什么样的理由?这是否回答了您的问题?相关但不完全重复的问题:因为C++标准是这么说的?你可以给我一些链接吗?
    A some_object;
    some_object.fun();