2017-01-02 58 views
1

以下代码编译正常。C++编译过载错误

#include <iostream> 
#include <vector> 
using namespace std; 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     x.resize(2); 
     x[0] = 10; 
     x[1] = 100; 
    } 
    std::vector<int> getValue() 
    { 
     return x; 
    } 
    const std::vector<int>& getValue() const 
    { 
     return x; 
    } 
private: 
     std::vector<int> x; 
}; 


int main() 
{ 

    MyClass m; 
    std::vector<int> y = m.getValue(); 
    for(int i=0; i<y.size(); i++) 
    { 
     std::cout<<y[i]<<std::endl; 
    } 

    const std::vector<int>& z = m.getValue(); 
    for(int i=0; i<z.size(); i++) 
    { 
     std::cout<<z[i]<<std::endl; 
    } 
    return 0; 
} 

然而,当我改变“的std ::矢量的getValue()”到更正确的版本(因为该函数应该改变对象)加入“常量”(标准::矢量的getValue( )const)它给出了下面的编译错误。

error: 'const std::vector<int>& MyClass::getValue() const' cannot be overloaded const std::vector<int>& getValue() const 

这是为什么?

我曾用“gcc版本4.8.4(Ubuntu的4.8.4-2ubuntu1〜14.04.3)”

+0

我不知道,但也许经过及(地址运算符)的回报:常量的std ::矢量及的getValue()const的 { 回报&X; } –

+2

发布不能编译的版本。 –

+1

@RSahu第一个代码是正确的,后面所述的变更在发布后会打破代码 –

回答

5

你无法定义具有相同名称的两个函数,其区别仅仅在于返回类型。因此,与不同的名称来定义的功能,例如:

std::vector<int> getValueCopy() const; 
3

通过添加const来渲染到getValue暧昧调用的第一个函数:什么是那些2个功能之间的区别:

std::vector<int> getValue() const;  // 1 
const std::vector<int>& getValue() const; // 2 

那么,他们是一样的,除了返回值,但等待!您不能基于C++中的返回类型进行重载!这是没有道理的,大多数电话会不明确:

std::vector<int> y = m.getValue(); // which one? It can be 1, it can be 2 (std::vector<int> 
            // is not a better match than const std::vector<int>&) 

const std::vector<int>& z = m.getValue(); // same as above 

m.getValue(); // which one? 

但是,也应该是两者之间的区别是什么?

第一个是100%安全的,而第二个不是:可以存储对x的引用,如果对象被破坏,它将成为悬挂引用。如果可能的话,我会说你摆脱了第二个。

+0

我明白,C++不允许重载仅在返回类型上有所不同的函数,以避免含糊不清。但在这个例子中,真的存在歧义吗? const std :: vector &z = m.getValue()显然需要返回地址,而第一个需要返回一个副本! – Soo

+0

@Soo是的,真的有歧义:你可以用一个右值(第一个'getValue')*或*用另一个引用(第二个'getValue')初始化'const&'。两者都是可能的,编译器不知道你想调用哪一个(即使它很明显)。值得注意的是,如果您要编写'std :: vector &v = m.getValue()',则不存在歧义,因为您无法使用右值初始化引用,因此选择了第二个重载。 – Rakete1111

1

您的问题是,你不理解函数重载的概念

当重载函数的函数的定义必须由类型参数或在参数列表参数的数量各不相同。

您不能重载只有返回类型不同的函数声明。

在你的函数:

std::vector<int> getValue() const 

const std::vector<int>& getValue() const 

只在返回类型不同,因此将不被视为重载函数

最好的方式来纠正你的错误是改变你的第二个函数名getValuev2()

或变更参数的功能之一的。

你可以阅读更多关于用C++超载: https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

+1

其实您发布的功能都是有效的重载。后面的'const'使所有的区别。 – juanchopanza

+0

@juanchopanza在重载概念中是无效的,因为它只在返回类型上有所不同,但为什么尾部的'const'会使所有区别? – Oghli

+1

是的,这意味着两个函数*不*仅在返回类型上有所不同。 – juanchopanza