简体   繁体   中英

in c++ why we declare reference parameter as const in overloaded function?

friend ostream &operator<<(ostream &output, 
                           const Distance &D)
{ 
    output << "F : " << D.feet << " I : " << D.inches;
    return output;            
}

Because you don't want the function that writes a instance to a stream to modify the instance.

And because a const reference, unlike a non-const one (unless you're using MSVC) can accept a temporary object, which is useful.

  1. Safety : with const we make sure we won't accidentaly modify the object.
  2. Speed : References are much faster than passing by value. Also const tells the compiler the object won't be modified, therefore some optimizations could be made.

恕我直言:按引用传递比通过复制传递更有效率,而const关键字阻止您更改原始实例...

in c++ why we declare reference parameter as const in overloaded function?

No, in the function that you've posted it's done so for the reasons mentioned in the other answers, but there's no requirement ie the standard doesn't mandate that an overloaded function taking a reference parameter should be const .

You're mixing up multiple things here. Overloading is a language feature where multiple functions with identical names can coexist, while const is a qualifier which says the data wouldn't change in a given context through that variable/function. They've no relationship that ties them saying it has to be a const if the overloading function takes a reference paramater. The same goes for reference variables too; they're just an alias (a different name) of another variable which has nothing to do with const or function overloading.

It is not obligatory to define a reference parameter as const in overloaded functions. Simply in your example of the operator << the right operand is not changed in the function. This allows to use this operator with const objects.

For example

#include <iostream>

class Distance
{
public:
   //...
   friend ostream &operator<<(ostream &output, 
                              const Distance &D)
   { 
       output << "F : " << D.feet << " I : " << D.inches;
       return output;            
   }
private:
   float feet;
   //...
};

int main()
{
   const Distance d1;

   std::cout << d1 << std:;endl;
}

The compiler would issue an error parsing statement

   std::cout << d1 << std::endl;

if the second parameter in the operator << would be declared as a non-const reference.

Another example

#include <iostream>

struct A
{
   A() {}
   A( A & ) { std::cout << "A( A & )" << std::endl; }
   A( const A & ) { std::cout << "A( const A & )" << std::endl; }
};

int main()
{
   A a1;
   A a2( a1 );
   const A a3;
   A a4( a3 );
}

In this example there are two copy constructors one of which defines the parameter as non-const reference and the other defines the parameter as const reference.

If there would not be the second copy constructor then the compiler would issue an error parsing statement

   A a4( a3 );

a function signature is a contract between the calling code and the function code.

You want that the function will require as less demands as possible. If you write demanding signature like ostream &operator<<(ostream &output, Distance &D)

then you won't be able to call your operator from code that operates on const objects:

void Foo(const Distance& d) {
  cout << d;  // syntax error
}

in other words putting as less requirements as possible on function arguments makes your function more general.

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