在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。建议这样做以避免对对象进行意外修改。
如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。
评论前必须登录!
注册