cpp►引用变量,按值与按引用传递返回及销毁
Posted itzyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cpp►引用变量,按值与按引用传递返回及销毁相关的知识,希望对你有一定的参考价值。
■引用变量
int rats;
int& alias = rats; // 使alias成为rats的【别名】
#include <iostream>
int main() {
using namespace std;
int rats = 101;
int& alias = rats;// alias是一个引用,它是rats的“别名”
cout << "rats = " << rats;
cout << ", alias = " << alias << endl;
rodents++;
cout << "rats = " << rats;
cout << ", alias = " << alias << endl;
rats++;
cout << "rats = " << rats;
cout << ", alias = " << alias << endl;
cout << "rats address = " << &rats;
cout << ", alias address = " << &alias << endl;
return 0;
}
rats = 101, alias = 101
rats = 102, alias = 102
rats = 103, alias = 103
rats address = 00CFF6E4, alias address = 00CFF6E4
从输出结果可以看到,alias是rats的一个别名,所以它俩的地址总相同,它俩的值总是同步更新的。
引用更接近指针常量,必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于它(不易主)。——地址与地址上存的值总相同。
必须在声明引用时将其初始化,而不能像指针那样先声明再赋值:
int rat;
int& rodent;
rodent = rat; // 不允许
- 块作用域
void go() {
Box box;
// ...
}// 块结束,box对象被销毁
while(...) {
int temp;
// ...
}// 块结束,temp被回收
- 按值传递给函数参数
#include <iostream>
class Box {
private:
int width;
int height;
public:
Box(int w, int h);
int getW() { return width; }
int getH() { return height; }
void go(Box box);
};
Box::Box(int w, int h) : width(w), height(h) {};
void Box::go(Box box) {
box.width = 1;
box.height = 2;
std::cout << "Inner:" << box.width << " , " << box.height << std::endl;
}
int main() {
Box box(10, 20);
box.go(box);
std::cout << "Outer:" << box.getW() << " , " << box.getH();
}
Inner:1 , 2
Outer:10 , 20
从输出结果可以看到,按值传递进函数的实参其实是拷贝了一份副本给形参,所以更改形参数据完全不会影响原实参。
形参对象销毁过程:Box box; => Box copyBox(调用复制构造函数); => copyBox在函数块作用域完成相关操作 => copyBox销毁。
原始实参和函数形参在内存中是分开存储的,如下图:
- 按引用传递给函数参数
void Box::go(Box& box) {
box.width = 1;
box.height = 2;
std::cout << "Inner:" << box.width << " , " << box.height << std::endl;
}
int main() {
Box box(10, 20);
box.go(box);
std::cout << "Outer:" << box.getW() << " , " << box.getH();
}
Inner:1 , 2
Outer:1 , 2
从输出结果可以看到,传递进去的实参与形参是同一个对象,它们的地址是相同的。
由于形参是实参的一个别名,所以它是与实参生命周期相同,在main()块结束时自动一同销毁。
- 函数返回类型为值类型
Box go() {
Box box(10, 20);
return box;
}
对象box先拷贝一份copyBox(调用复制构造函数),成为返回对象,它与原box对象地址空间是不一样的。然后函数块作用域结束,box对象被析构销毁掉。
- 函数返回类型为引用类型
Box& go() {
Box box(10, 20);
return box;
}
返回的对象box的别名就是最终要返回的引用,返回值为引用型(Box&)的时候,返回的是地址。当函数返回引用类型时,没有复制返回值,返回的是对象本身。
那么,box对象在函数块结束时,会被销毁吗?当然会被销毁了,因为box对象就是典型的局部变量啊!所以,返回box对象地址后,box对象就被析构了,返回的引用对象就有问题了。所以用法是这样的:
Box& go(Box& b, ...) {
// 操作b
return b;
}
就是从外面传入一个对象引用,这个对象的生命周期就不在函数块作用域,所以传入的对象不会被销毁!就一切正常正确了。
以上是关于cpp►引用变量,按值与按引用传递返回及销毁的主要内容,如果未能解决你的问题,请参考以下文章