函數返回值(包含const返回值解析)

如何返回值

1.返回值非引用

primer說函數返回值用於初始化函數調用點的一個臨時對象,所以返回值到臨時對象是第一次拷貝,臨時對象到接收值的變量是第二次拷貝

string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr > 1) ? word : word+ending;    //到臨時對象有一次拷貝。
} 

如果把返回值設爲引用,就省去了拷貝。

問題:那個調用點的臨時對象是const嗎?

2.返回值是引用

如果是引用類型,中間不用發生任何拷貝

3. 實例探究

const非引用作用:

不讓其作爲左值,在作爲右值時和非const一樣都是const屬性。

const引用作用:

讓返回值有const屬性。但用於對其他對象進行拷貝時,是不是const都能進行。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

//1和2用於探究返回值是const非引用
string shorterString1(string s1, string s2)
{
    return s1.size()<=s2.size() ? s1:s2;
}

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

//3和4用於探究返回值是const引用
string &shorterString3(string &s1, string &s2)
{
    return s1.size()<=s2.size() ? s1:s2;
}

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


int main() {

   string s1 = "123";
    string s2 = "456";
    string s3 = shorterString1(s1, s2);
    string s4 = shorterString2(s1, s2);

    shorterString1(s1, s2) = "456";
    shorterString2(s1, s2) = "456";    //xxx, 作爲左值const有用了

    string &s3p = shorterString1(s1, s2); //xxx,cannot bind non-const lvalue reference to an rvalue of type 'const string',作爲右值const沒用啊
    string &s4p = shorterString2(s1, s2); //xxx,兩者都不能綁定
    
    //=====================================
    string &s5= shorterString3(s1, s2);
    string &s6= shorterString4(s1, s2); //xxx, binding reference of type 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string<char>&'} to 'const string' {aka 'const std::__cxx11::basic_string<char>'} discards qualifiers

    string s7= shorterString3(s1, s2); //這倆都是拷貝,和 是不是返回值const無關
    string s8= shorterString4(s1, s2);
    return 0;
}

不要返回局部變量的指針或引用

局部變量在函數返回後會消亡,所以地址無效。

下面是錯誤,其中建立一個const char[6]的數組,不能把非const綁定到const。

string &manip()
{
    return "Empty"; //xxx,cannot bind non-const lvalue reference of type 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string<char>&'} to an rvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'}
}

下面是警告,綁定到一個臨時對象。

const string &manip()
{
    return "Empty";  // warning: returning reference to temporary
}

引用返回左值

只有引用返回左值,其他返回右值。想引用不能修改,就加上const限定

#include <iostream>
#include <vector>
#include <string>
using namespace std;

char &get_val1(string &s, string::size_type position)
{
    return s[position];
}

char get_val2(string &s, string::size_type position)
{
    return s[position];
}

const char &get_val3(string &s, string::size_type position)
{
    return s[position];
}

int main() {

    string s ="123";
    get_val1(s, 0) = '1';
    get_val2(s, 0) = '1'; //xxx,函數是右值,人家要左值lvalue required as left operand of assignment
    get_val3(s, 0) = '1'; //xxx,const左值不能修改
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章