函数重载只能通过C ++中的返回值和const来完成?

时间:2012-03-22 23:25:48

标签: c++ overloading

除了返回类型和常量之外,是否可以使用相同函数的两个版本?

我不这么认为。以下示例显示了这一点。但我不知道原因。

#include<iostream>
using namespace std;
class A
{
 private:
       int bb ;
 public:
       double f1(int a) const {cout << "double f1 is called " << endl; return 0.0; }
       int f1(int a) {cout << "int f1 is called " << endl ; return 0; }

};

int main()
{
     int b = 6;
     A aa;

     double c= aa.f1(b);
     return 0 ;
}

输出:

调用int f1

为什么双f1(int a)const不能计算?

4 个答案:

答案 0 :(得分:4)

出于显而易见的原因,你不能在返回类型上重载。

可以重载隐式实例参数的常量。比较:

aa.f1(b);
static_cast<A const &>(aa).f1(b);

(这个例子也说明了为什么尝试“在返回类型上重载”没有意义:在这个例子中你会如何做出决定?)

答案 1 :(得分:4)

我猜主要问题是它容易引入歧义。例如:

int main()
{
  int b = 6;
  A aa;

  float c= aa.f1(b); // which version of f1 is called here?
  return 0 ;
}

它是int版本并且值被提升为float,还是双版本并且值被截断?

一种可能的解决方案是将返回值移动到参考参数:

void f1(int a, double &out);
void f1(int a, int &out);

然后编译器可以计算出哪一个要调用,或者如果没有匹配类型则生成错误。

答案 2 :(得分:2)

我同意Skizz,这里的歧义是不安全的。 在你给出的例子中,我们永远不知道最后会调用两者中的哪些方法 (甚至想知道它是否可能依赖于编译器?)。

就我而言,在C ++中创建具有相同名称但不同const的成员函数的主要兴趣是在成员数据上创建const /非const访问器。

示例:

class Foo {
    private: Data m_Data;

    public: Data& getData(void) { return m_Data; }
    public: const Data& getData(void) const { return m_Data; }
};

两个访问器getData()都检索成员属性m_Data的引用。 当您在可修改的Foo实例上进行调用时,第一个返回可修改的数据。 第二个在const Foo实例上调用时返回一个const数据。

否则,我会建议避免这种设计。

此致,

答案 3 :(得分:1)

除非您将返回类型声明为常见的超类型,例如void *,然后将结果转换回您需要的内容。这当然是非常邪恶的。

您可能会考虑将返回类型包装在一个对象中,该对象可以很聪明地包含哪种解决方案。这就是大多数OO系统最终经常做的事情,这就是封装可能非常有用的一个原因。

这也是泛型如何令人敬畏。我必须检查我的C ++语法,但是您可以声明一个函数,其返回类型与其参数类型相关,或者基于子类的泛型。

但是对于基类型,不,不是真的。