c++ const左值引用绑定临时变量

以前一直以为左值引用只能绑定变量,不能绑定像字符串常量这类的临时变量。但实质上是可以的,只需要把左值引用定义为const类型,就可以绑定给无名右值(如常量字符串、加减运算导致的临时变量等)

例:

const string& a = "ABC";

但是当定义指针引用时这么操作可能会有些搞脑子,以下面代码为例

定义printout函数:

void printout(char*& str){  //报错,右值不能赋给非常量左值引用
    cout<<str<<endl;
}

void printout(const char*& str){  //报错,右值不能赋给非常量左值引用
    cout<<str<<endl;
}

void printout(string& str){  //报错,右值不能赋给非常量左值引用
    cout<<str<<endl;
}

void printout(const string& str){ //正确
    cout<<str<<endl;
}


printout("ABC");

以上只有最后一种情况正确,其他都会报错。继续考察char*&这种指针引用形式,如何让它合法:

void printout(char* const& str){ //合法,但会报warning:ISO C++ forbids converting a string constant to 'char*'
    cout<<str<<endl;
}

void printout(const char* const& str){ //合法,无warning
    cout<<str<<endl;
}

printout("ABC");

主要对比const char*&和char* const&这两种情况。前者其实表示指针指向的内容不可修改,但指针本身可变;后者则表示指针指向的内容可以被修改,但指针指向的地址不可变。由于左值引用绑定右值的前提是引用不可变,即代表引用指向的地址不变,所以当指针作为左值时,要用const直接修饰指针,也就是上述两种情况的后者。

而const char* const&能保证不报warning的原因主要是避免把常量字符串赋值给char*的提示而已。

继续研究常量左值引用能不能绑定函数返回的临时变量。首先定义类Student,其中定义了两种构造函数,一个析构函数以及重载赋值运算符。还有一个能返回一个对象的函数printStudent,目的是探索函数返回的临时对象被绑定后,生命周期是否被延长

struct Student
{
    public:
    int member;
    Student(){cout<<"constructing 0"<<endl;}
    Student(int m): member(m){cout<<"constructing 1"<<endl;};
    Student printStudent();
    ~Student();
    void operator= (const Student& s);
};

Student Student::printStudent(){
    Student a = 111;
    cout<<"&a in Student: "<<&a<<endl;
    return a;
}

Student::~Student(){
    cout<<"xigou hanshu "<<member<<endl;
}

void Student::operator= (const Student& s){
    this->member = s.member;
    cout<<"copying..."<<endl;
}

执行以下测试代码:

int main(){
    Student s = 2;
    Student const& p = s.printStudent();
    cout<<&p<<endl;
    return 0;
}

/*
输出结果:
constructing 1
constructing 1
&a in Student: 0x62fe04
0x62fe04
xigou hanshu 111
xigou hanshu 2
*/

首先,我们发现由printStudent返回的临时变量并没有被栈回收(析构函数在cout之后才被调用),否则输出p的地址将报错。其次,我们发现构造函数只被调用过两次,说明将s.printStudent()返回值赋值给p时,没有触发新的构造函数,同时也没有触发等号赋值运算符。最后,我们发现p指向的地址与函数中的临时变量地址一致,验证了函数返回值被常量引用绑定后的生命周期被延长的观点。

这一段总结,如果想要延长函数返回的临时变量的生命周期,可以用常量左值引用对其进行绑定(右值绑定似乎也可以)。不过这样做之后,函数的出栈操作是如何实现的暂时就不知道了,需要继续查阅资料

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值