个性化阅读
专注于IT技术分析

我们什么时候通过引用或指针传递参数?

在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。建议这样做以避免对对象进行意外修改。

如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。

赞(0) 打赏
未经允许不得转载:srcmini » 我们什么时候通过引用或指针传递参数?
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

微信扫一扫打赏