Explore: considerations for function return references in C++

  • 2020-04-02 01:01:07
  • OfStack

The return value of a function is different from the return reference
When a function returns a value, it produces a temporary variable as a copy of the return value of the function, and when it returns a reference, it does not produce a copy of the value. This must be clear, or you will not understand what a return reference is. Here are some examples:
1, references the function's argument, which is also a reference

const string &shorterString(const string &s1,const string &s2)
      {
             return s1.size()<s2.size()?s1:s2;
      }

The return value of the above function is the reference type. These string objects are not copied when the function is called and the result is returned, whether it returns s1 or s2. Simply put, the reference returned is the parameter s1 or s2 of the function, and again s1 and s2 are also references, not generated in the body of the function. A local object in a function cannot be called because the local object is released after the function is called.

2. Never return a reference to a local object

const string &mainip(const string &s)
      {
             string ret=s;
             return ret;
      }


When the function is executed, the program frees the storage space allocated to the local object. At this point, a reference to a local object points to an uncertain memory.
3. Cannot return an object defined inside a function. In the member function of the class, the class object that returns the reference cannot be the class object defined in the function (it will be released), which is generally the object that this points to. A typical example is the assignment function of the string class.

<SPAN style="COLOR: #000066; FONT-SIZE: 16px">String& String::operator =(const String &str)  //Notice why a function USES a reference when compared to a +? A is equal to b is equal to c
{
 if (this == &str)
 {
  return *this;  
 }
 delete [] m_string;
 int len = strlen(str.m_string);
 m_string = new char[len+1];
 strcpy(m_string,str.m_string);
 return *this;
}</SPAN>

This is not the same as the "+" operator overloading in the sting class. An overload of the "+" operator cannot return a reference because it returns a class object defined within the function, with code attached.

<SPAN style="COLOR: #000066; FONT-SIZE: 16px">String String::operator +(const String &str)    
{
 String newstring;
 if (!str.m_string)
 {
  newstring = *this;
 }
 else if (!m_string)
 {
  newstring = str;
 }
 else
 {
  int len = strlen(m_string)+strlen(str.m_string);
  newstring.m_string = new char[len+1];
  strcpy(newstring.m_string,m_string);
  strcat(newstring.m_string,str.m_string);
 }
 return newstring;
}</SPAN>

4, the reference returns an lvalue (the = assignment in the above example is the same, i.e. a=b=c is ok)

 char &get_val(string &str,string::size_type ix)
      {
             return str[ix];
      }
       Call with statement :
       string s("123456");
       cout<<s<<endl;
       get_val(s,0)='a';
       cout<<s<<endl;

Finally, turn the code as a summary.

<span style="font-size:16px;color:#000066;">#include<iostream>
using namespace std;
string make_plural(size_t,const string&,const string&);
const string &shorterString(const string &,const string &);
const string &mainip(const string&);
char &get_val(string &,string::size_type);
int main(void)
{
    cout<<make_plural(1,"dog","s")<<endl;
    cout<<make_plural(2,"dog","s")<<endl;

    string string1="1234";
    string string2="abc";
    cout<<shorterString(string1,string2)<<endl;

    cout<<mainip("jiajia")<<endl;

    
    string s("123456");
    cout<<s<<endl;
    get_val(s,0)='a';

    cout<<s<<endl;

    getchar();
    return 0;
}
//Return non-reference
string make_plural(size_t i,const string &word,const string &ending)
{
    return (i==1)?word:word+ending;
}
//Returns the reference
const string &shorterString(const string &s1,const string &s2)
{
    return s1.size()<s2.size()?s1:s2;
}
//It is forbidden to return a reference to a local object (my dev c++ did not report an error, which is scary)
const string &mainip(const string &s)
{
    string ret=s;
    return ret;
}
//The reference returns an lvalue
char &get_val(string &str,string::size_type ix)
{
    return str[ix];
}</span>


Related articles: