为什么非const方法会隐藏const重载?

时间:2015-03-05 13:26:59

标签: c++ reference override const

鉴于以下代码:

class A
{
public:
    A(): value( 0 ) {}

    int* get()
    {
        return &value;
    }

    const int& get() const
    {
        return value;
    }

private:
    int value;
};

int main()
{
    A a;
    const int& ref_value = a.get();
}

导致以下编译错误:

prog.cpp: In function 'int main()':
prog.cpp:23:35: error: invalid conversion from 'int*' to 'int'
      const int& ref_value = a.get();
                                   ^

似乎带有const修饰符的重载get()方法确实被完全忽略,编译器只看到它的非const定义。这是可以理解的,因为一个对象不是常数。一种解决方案是使 a 对象保持不变。虽然还有其他两个解决方案使代码可编译:

  1. 通过添加不同的名称或其他参数来更改const get()方法的签名。

    int* get();
    const int& get_changed() const; <-- this gets called
    
  2. 更改非const get()方法以返回引用而不是指针。

    int& get(); <-- this gets called
    const int& get() const; 
    
  3. 虽然有

    int* get();
    const int& get() const;
    

    我们遇到编译错误。

    令我困惑的是所有这些行为背后的原因。

2 个答案:

答案 0 :(得分:3)

原因是编译器无法根据不同的返回类型执行重载解析。

过载分辨率仅考虑功能签名。函数签名只包含函数名,参数和cv限定符 - 而不是返回类型。

答案 1 :(得分:3)

如果同一函数的const和非const重载具有相同的参数,则调用哪一个取决于{{1}上仅 你正在调用该函数的对象的ness。因此,在非const const 上调用必须调用非a重载。

与此情况完全相同:

const

可以在非void foo(int *p); void foo(const int *p); int main() { int i; const int ci; foo(&i); // Calls the first overload foo(&ci); // Calls the second overload } 限定对象上调用const - 限定函数 ,但这需要对#con;&#34;转换。如果超载不需要这样的转换(更好的匹配),那么它将是首选。