在C++中, 由于以下原因, 变量通过引用传递:
1)要修改调用者函数的局部变量:引用(或指针)允许被调用函数修改调用者函数的局部变量。例如, 考虑以下示例程序, 其中fun()能够修改局部变量Xof主要().
void fun( int &
x) {
x = 20;
}int main() {
int x = 10;
fun(x);
cout<
<
"New value of x is " <
<
x;
return 0;
}
输出如下:
New value of x is 20
2)对于传递大型参数:
如果实参很大,通过引用(或指针)传递更有效,因为实际上只传递一个地址,而不是整个对象。例如,让我们考虑下面的Employee类和打印员工详细信息的printEmpDetails()函数。
class Employee {
private :
string name;
string desig;
//More attributes and operations
};
void printEmpDetails(Employee emp) {
cout<
<
emp.getName();
cout<
<
emp.getDesig();
//Print more attributes
}
上面的代码的问题是:每次printEmpDetails()调用后, 将构造一个新的Employee对象, 其中涉及创建所有数据成员的副本。因此, 更好的实现方法是将Employee作为参考。
void printEmpDetails( const Employee &
emp) {
cout<
<
emp.getName();
cout<
<
emp.getDesig();
//Print more attributes
}
这一点仅对结构和类变量有效, 因为我们对int, char等基本类型没有任何效率优势。
3)为了避免对象切片:如果将子类对象传递给期望超类对象的函数,则按值传递的对象将被切片。例如,考虑下面的程序,它打印“This is Pet Class”。
#include <
iostream>
#include<
string>
using namespace std;
class Pet {
public :
virtual string getDescription() const {
return "This is Pet class" ;
}
};
class Dog : public Pet {
public :
virtual string getDescription() const {
return "This is Dog class" ;
}
};
void describe(Pet p) { //Slices the derived class object
cout<
<
p.getDescription()<
<
endl;
}int main() {
Dog d;
describe(d);
return 0;
}
【我们什么时候通过引用或指针传递参数()】输出如下:
This is Pet Class
如果我们在上述程序中使用了按引用传递, 那么它将正确打印” This is Dog Class” 。请参阅以下修改的程序。
#include <
iostream>
#include<
string>
using namespace std;
class Pet {
public :
virtual string getDescription() const {
return "This is Pet class" ;
}
};
class Dog : public Pet {
public :
virtual string getDescription() const {
return "This is Dog class" ;
}
};
void describe( const Pet &
p) { //Doesn't slice the derived class object.
cout<
<
p.getDescription()<
<
endl;
}int main() {
Dog d;
describe(d);
return 0;
}
输出如下:
This is Dog Class
这一点对于基本数据类型(例如int, char等)也无效。
4)在函数中实现运行时多态
我们可以通过将对象作为参考(或指针)传递给它来使函数变为多态。例如, 在以下程序中, print()接收对基类对象的引用。如果传递了基类对象, 则print()调用基类函数show();如果传递了派生类对象, 则调用派生类函数show()。
#include<
iostream>
using namespace std;
class base {
public :
virtual void show() {//Note the virtual keyword here
cout<
<
"In base \n" ;
}
};
class derived: public base {
public :
void show() {
cout<
<
"In derived \n" ;
}
};
//Since we pass b as reference, we achieve run time polymorphism here.
void print(base &
b) {
b.show();
}int main( void ) {
base b;
derived d;
print(b);
print(d);
return 0;
}
输出如下:
In base
In derived
谢谢文基添加这一点。
附带说明一下, 建议的做法是:仅由于原因而通过引用传递引用参数时, 使引用参数为const。上述2或3。建议这样做以避免对对象进行意外修改。
如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。
推荐阅读
- Quicksort最坏的情况何时发生()
- C++中什么时候使用初始化列表()
- MySQL事务
- Linux下如何使用 vmstat 命令
- MySQL日志管理
- go语言学习--函数
- #yyds干货盘点#ping(测试主机之间网络的连通性)
- 基于Vue3+Vite+TS,二次封装element-plus业务组件
- #yyds干货盘点#Prometheus 之 Exporter 详解