简体   繁体   中英

Function const return type: invalid initialisation of reference of type

I have this function:

Triangle& Triangle::get_largest_triangle(const Triangle& t) const
{
    float area_this = get_area();
    float area_other = t.get_area();

    if (area_other > area_this)
        return *this;
    else
        return t;
}

This doesn't work unless I declare the returned Triangle to be constant, ie:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

Why is this? I'm fairly new to C++ but as far as I can tell, neither 'this', nor the object in the parameter list are being changed in the function so I don't really see what the issue is.

eg What if I want to change some of the values stored in the largest Triangle after running this function?

This function returns a non-const reference to a Triangle. This means that the caller can modify the returned object. But it returns either a reference to itself (which is const due to the function declaration), or a reference to the function argument (which is also const). So the compiler won't allow it because you are making a const object non-const.

Your options are to change the function signature to return a const:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

or alternatively to make the method non-const and take a non-const reference:

Triangle& Triangle::get_largest_triangle(Triangle& t)

When you return t , you return const Triangle& , which is the type of t .
when you declare your function to return Triangle& you are returning different type. remember, const is part of the type.
Triangle& is not const Triangle& .

Just change the return type of get_largest_triangle to be const Triangle& , or change the type of t to be Triangle& . both have their cons and pros.

Consider following use of your function

const Triangle t1, t2;
Triangle &t3 = t1.get_largest_triangle(t2);

t3 is now modifiable but this is reference to either t1 or t2 . So your code can 'accidentally' drop constness of objects. If this was possible c++ type system wouldn't be safe.

Theoretically because t1 and t2 are const they could be allocated in non modyfiable memory and when you will try to change one of them via t3 which you are allowed to do, program can crash.

You're trying to convert t , a reference to a const Triangle , to a reference to a modifiable Triangle . That would allow the caller to modify t , which would be a bad thing.

You need to change your return type to make it const .

You have defined your function being const , ie not changing the state of the object:

Triangle& Triangle::get_largest_triangle(const Triangle& t) const

The problem is that you return a non const reference:

  • if your return *this, the non const reference could be used to change the object's state.
  • if you return t, the non const reference could be used to modify an object which you said taht you wouldn't change.

This is why the compiler complains. Just say that you return a reference to a const to solve your issue:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

Passing a const reference to the method the compiler guarantees that the object won't be changed. You try to return a non-const reference of the same object, which would lead to t loosing its constness, and the compiler is preventing you from doing that.

Rethink if you're doing the right thing here. Why can't you either use a non-const reference for t, or return a const reference?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM