C ++成员函数具有相同的名称和参数,不同的返回类型

时间:2016-09-08 21:22:45

标签: c++

如果我在类中定义具有相同名称和参数但不同返回类型的成员函数,它是否有效:

B

如果我们有以下代码,会调用哪个成员函数?

class Test {
public:
    int a;
    double b;
}

class Foo {    
private:
    Test t;
public:
    inline Test &getTest() {
        return t;
    }
    inline const Test &getTest() const {
        return t;
    }
}

5 个答案:

答案 0 :(得分:5)

不,它无效,但在您的示例中是,因为最后const实际上是签名的一部分(隐藏的Foo *this第一个参数现在是const Foo *this)。

它用于以只读方式访问(获取const引用,方法是常量),或者写入(获取非const引用,方法不是常量)

当然,在两种方法中返回同一实体的引用(常量或非常量)仍然是一个很好的设计选择!

答案 1 :(得分:3)

没有

您不能在返回类型上重载。

为什么呢?标准是这样说的。

它实际上是有道理的 - 你无法确定在所有情况下要调用的函数。

答案 2 :(得分:3)

具有相同形式参数列表的Const和非const方法可以并排显示,因为this指针被视为隐藏参数,并且具有不同的类型。这可用于提供变异和非变异访问器,如问题中的代码所示。

如果签名完全相同,则为no。

答案 3 :(得分:1)

通过示例扩展先前的答案和您给定的代码,以便您可以在以下情况下实际告知调用的内容:

#include <iostream>

class Test {
public:
    int a;
    double b;
};

class Foo {
private:
    Test t;
public:
    inline Test &getTest() {
        std::cout << "Non const-refrence " << std::endl;
        return t;
    }
    inline const Test &getTest() const {
        std::cout << "Const-refrence " << std::endl;
        return t;
    }
};

int main() {
    Foo foo;
    Test& t1 = foo.getTest();
    const Test& t2 = foo.getTest();

    const Foo bar;
    const Test& t3 = bar.getTest();

    return 0;
}

输出:

Non const-refrence
Non const-refrence
Const-refrence

在第二个getTest签名之后看到的const告诉编译器,由于调用此函数,不会修改任何成员变量。

答案 4 :(得分:1)

  

如果我定义具有相同名称和参数但具有不同返回类型的成员函数[...],它是否有效?

没有。 既不是方法类也不是非类函数。

原因是含糊不清。在某些情况下,编译器只能通过推导返回的值来选择正确的重载。

总之:您不能基于返回类型重载方法。

在您的示例中,这两种方法:

 Test& getTest();
 const Test& getTest() const;

正确重载是因为签名不同,但不是,因为返回值不同!

实际上,函数签名由以下内容组成:

  • 功能名称
  • cv修饰符
  • 参数类型
  • 方法限定符

所以你方法的签名是:

1) getTest();
2) getTest() const;
              ^------ Note that const qualifiers of the method is part of signature

您可以注意到,返回值是不是签名的一部分,但方法限定符的 const 是。

  

如果我们有以下代码,会调用哪个成员函数?

使用以下代码:

Foo foo;
Test& t1 = foo.getTest();
const Test& t2 = foo.getTest();

在案例t2中,它只会调用非常规方法甚至

原因是foo对象在该范围内是no-const,所以每个 方法将以非常量形式调用。

详细信息,在第三行:

const Test& t2 = foo.getTest();

foo.getTest()会在之后返回no-const引用和const引用中隐式转换。

如果要强制编译器调用const版本,则应在foo中“临时转换”对象const

例如:

const int& t2 = static_cast<const Foo&>(foo).getTest();

在这种情况下,我得到一个const引用该对象,因此该对象将被视为const,并且将调用适当的const方法。