返回引用
引用和指针
1.问题提出
这个问题来源于我在刷用队列实现栈这道题目的时候,我写成了这样的一个代码:
class MyStack {
public:
MyStack() {
}
void push(int x) {
qOne.push(x);
}
int pop() {
while (qOne.front() != qOne.back()) {/*这行代码对么?*/
qTwo.push(qOne.front());
qOne.pop();
}
int result = qOne.front();
qOne.pop();
qOne.swap(qTwo);
while (!qTwo.empty()) {
qTwo.pop();
}
return result;
}
int top() {
return qOne.back();
}
bool empty() {
return qOne.empty();
}
};
我需要用queue实现stack,实现POP操作时需要将queue的元素先拿出来,剩下最后一个,这里需要判断qOne队列是否有一个元素,我看到front函数返回的是引用,又想到引用和指针都是地址的概念,这个应该会像指针一样把?地址又不会重复,结果出错了。。。。。。
看到下面的int result = qOne.front()我才知道有多蠢,本身返回的就是一个值而已,我用size判断知否留一个元素就好了:
int pop() {
int size = qOne.size();
size--;
while (size--) {
qOne.push(qOne.front());
qOne.pop();
}
int result = qOne.front();
qOne.pop();
return result;
}
由此我有个疑问,指针和引用有什么区别?我直接返回指针不好么?
2.指针和引用的区别
指针和引用都是地址的概念,指针是指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。引用是别名,指针是地址,具体的:
- (1). 从现象上看,指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变。
- (2). 从内存分配上看,程序为指针变量分配内存区域,而不为引用分配内存区域,因为引用声明时必须初始化,从而指向一个已经存在的对象。
- (3). 不存在指向空值的引用这个事实,意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
- (4). 从编译上看,程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
为啥一定要返回指针呢?
3.const
引用更相当于一个不能改变指向的指针,并且const对于指针和引用的限定是有差别的:
3.1常量指针和常量引用
常量指针:指向常量的指针,在指针定义语句的类型前加const,表示指向的对象是常量。
常量引用:指向常量的引用,在引用定义语句的类型前加const,表示指向的对象是常量。也跟指针一样不能对引用指向的变量进行重新赋值操作。
3.2指针常量和引用常量
在指针定义语句的指针名前加const,表示指针本身是常量。在定义指针常量时必须初始化!而这是引用与生俱来的属性,无需使用const。
但是可以修改值,*pointer可以修改。
3.3常量指针常量和常量引用常量
常量指针常量:指向常量的指针常量,可以定义一个指向常量的指针常量,它必须在定义时初始化。
定义"const int* const pointer=&c"
告诉编译器,pointer和*pointer都是常量,他们都不能作为左值进行操作。
不存在所谓的"常量引用常量",因为引用变量就是引用常量。C++不区分变量的const引用和const变量的引用。程序决不能给引用本身重新赋值,使他指向另一个变量,因此引用总是const的。如果对引用应用用关键字const,起作用就是使其目标称为const变量。
4.传递的区别
当指针和引用作为函数的参数是如何传值的呢?
- 指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
- 引用传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
5.返回的区别
返回“值”和返回“引用”是不同的,函数返回值时会产生一个临时变量作为函数返回值的副本,而返回引用时不会产生值的副本。
c++返回的几种情况:
1)主函数main的返回值:这里提及一点,返回0表示程序运行成功。
2)返回非引用类型:函数的返回值用于初始化在跳用函数出创建的临时对象。用函数返回值初始化临时对象与用实参初始化形参的方法是一样的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。且其返回值既可以是局部对象,也可以是求解表达式的结果。
3)返回引用:当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。
由此我们可以看到为什么要返回引用?返回引用就可以省去临时赋值的步奏,节省时间。
返回引用需要注意:
-
- 返回引用,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。
int& abc(int a, int b, int c, int *result){
*result = a + b + c;
return *result;
}
*******
int& abc(int a, int b, int c, int& result){
result = a + b + c;
return result;
}
-
- 不要返回局部对象的引用。
参考:朝研行歌,keyouan2008