函数返回值(包含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 
#include 
#include 
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&'} to 'const string' {aka 'const std::__cxx11::basic_string'} 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&'} to an rvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string'}
}

下面是警告,绑定到一个临时对象。

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

引用返回左值

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

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

 

你可能感兴趣的:(C++语言)