C++ member functions with same name and parameters

2020-04-08 05:44发布

is it valid if I define member functions with same name&parameters but different return types inside a class like this:

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;
    }
}

Which member function gets called if we have following code?

Foo foo;  // suppose foo has been initialized
Test& t1 = foo.getTest();
const Test& t2 = foo.getTest();

标签: c++
5条回答
Animai°情兽
2楼-- · 2020-04-08 06:22

is it valid if I define member functions with same name&parameters but different return types [...]?

No. Neither a method class nor a non-class function.

The reason is ambiguity. There would be situation in which the compiler could not pick the right overloading only by deducing the returned value.

In conclusion: you can't overload methods based on return type.


In your example, those two methods:

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

Are correctly overloaded because the signature is different, but not because the return value is different!

Indeed, a function signature is made up of:

  • function name
  • cv-qualifiers
  • parameter types
  • method qualifier

So the signature of your methods are:

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

As you can notice, the return value is not part of signature, but the const of the method qualifier is.


Which member function gets called if we have following code?

With the following code:

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

It will call only the no-const method, even in the case t2.

The reason is that foo object is no-const in that scope, so each method will be called in its no-const form.

In details, in the third line:

const Test& t2 = foo.getTest();

foo.getTest() will return the no-const reference and after will be implicitly converted in a const reference.

If you want to force the compiler to call the const version, you should "temporary convert" the object foo in a const.

For example:

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

In that case I get a const ref to the object, so the object will be treated like a const and the proper const method will be invoked.

查看更多
Bombasti
3楼-- · 2020-04-08 06:40

no, it is not valid, but in your example it is, because the last const is actually part of the signature (the hidden Foo *this first parameter is now const Foo *this).

It is used to access in read-only (get const reference, the method is constant), or write (get non-const reference, the method is not constant)

it's still a good design choice to return the reference of the same entity (constant or non-constant) in both methods of course!

查看更多
▲ chillily
4楼-- · 2020-04-08 06:42

Const and non-const methods with the same formal parameter list can appear side-by-side because the this pointer is treated as a hidden argument and would have a different type. This may be used to provide mutating and non-mutating accessors as in the code in your question.

If the signatures are exactly the same, then no.

查看更多
forever°为你锁心
5楼-- · 2020-04-08 06:44

To expand upon the previous answers and your given code with an example so you can actually tell what's being called when:

#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;
}

With output:

Non const-refrence
Non const-refrence
Const-refrence

The const you see after the second getTest signature tells the compiler that no member variables will be modified as a result of calling this function.

查看更多
叼着烟拽天下
6楼-- · 2020-04-08 06:45

No.

You cannot overload on return type.

Why? The standard says so.

And it actually makes sense - you can't determine what function to call in all situations.

查看更多
登录 后发表回答