在C++中,基于以下如下我们通过以引用reference的形式传递变量。

  (1)To modify local variables of the caller function

  A reference(or pointer) allows called function to modify a local variable of the caller function.

  For example, consider te following example program where fun() is able to modify local variable x of main().

 1 #include<iostream>
2 using namespace std;
3
4 void fun(int &x)
5 {
6 x = 20;
7 }
8
9 int main()
10 {
11 int x = 10;
12 fun(x);
13 cout<<"New value of x is "<<x;
14 return 0;
15 }

  Output:

  New value of x is 20

  (2)For passing large sized arguments

  If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.
  For example, let us consider the following Employee class and a function printEmpDetails() that prints Employee details.

 1 class Employee
2 {
3 private:
4 string name;
5 string desig;
6
7 // More attributes and operations
8 };
9
10 void printEmpDetails(Employee emp)
11 {
12 cout<<emp.getName();
13 cout<<emp.getDesig();
14
15 // Print more attributes
16 }

  The problem with above code is: every time printEmpDetails() is called, a new Employee abject is constructed that involves creating a copy of all data members. So a better implementation would be to pass Employee as a reference.

1 void printEmpDetails(const Employee &emp)
2 {
3 cout<<emp.getName();
4 cout<<emp.getDesig();
5
6 // Print more attributes
7 }

  This point is valid only for struct and class variables as we don’t get any efficiency advantage for basic types like int, char.. etc.

  (3)To avoid object slicing

  If we pass an object of subclass to a function that expects an object of superclass then the passed object is sliced if it is pass by value.
  For example, consider the following program, it prints “This is Pet Class”.

 1 #include <iostream>
2 #include<string>
3
4 using namespace std;
5
6 class Pet
7 {
8 public:
9 virtual string getDescription() const
10 {
11 return "This is Pet class";
12 }
13 };
14
15 class Dog : public Pet
16 {
17 public:
18 virtual string getDescription() const
19 {
20 return "This is Dog class";
21 }
22 };
23
24 void describe(Pet p)
25 {
26 // Slices the derived class object
27 cout<<p.getDescription()<<endl;
28 }
29
30 int main()
31 {
32 Dog d;
33 describe(d);
34 return 0;
35 }

  Output:

  This is Pet class.

  

  If we use pass by reference in the above program then it correctly prints “This is Dog Class”.
  See the following modified program.

 1 #include <iostream>
2 #include<string>
3
4 using namespace std;
5
6 class Pet
7 {
8 public:
9 virtual string getDescription() const
10 {
11 return "This is Pet class";
12 }
13 };
14
15 class Dog : public Pet
16 {
17 public:
18 virtual string getDescription() const
19 {
20 return "This is Dog class";
21 }
22 };
23
24 void describe(const Pet &p)
25 {
26 // Doesn't slice the derived class object.
27 cout<<p.getDescription()<<endl;
28 }
29
30 int main()
31 {
32 Dog d;
33 describe(d);
34 return 0;
35 }

  Output:

  This is Dog class

  This point is also not valid for basic data types like int, char, .. etc.

  (4)To achieve Run Time Polymorphism in a function
  We can make a function polymorphic by passing objects as reference (or pointer) to it.

  For example, in the following program, print() receives a reference to the base class object. print() calls the base class function show() if base class object is passed, and derived class function show() if derived class object is passed.

 1 #include<iostream>
2 using namespace std;
3
4 class base
5 {
6 public:
7 virtual void show()
8 { // Note the virtual keyword here
9 cout<<"In base \n";
10 }
11 };
12
13
14 class derived: public base
15 {
16 public:
17 void show()
18 {
19 cout<<"In derived \n";
20 }
21 };
22
23 // Since we pass b as reference, we achieve run time polymorphism here.
24 void print(base &b)
25 {
26 b.show();
27 }
28
29 int main(void)
30 {
31 base b;
32 derived d;
33 print(b);
34 print(d);
35 return 0;
36 }

  Output:

  In base
  In derived

  As a side note, it is a recommended practice to make reference arguments const if they are being passed by reference only due to reason no. 2 or 3 mentioned above. This is recommended to avoid unexpected modifications to the objects.

  Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

  转载请注明:http://www.cnblogs.com/iloveyouforever/

  2013-11-25  21:56:14

  

When do we pass arguments by reference or pointer?的更多相关文章

  1. [NPM] Pass arguments to npm scripts

    Often times you’ll have variations that you’ll want to make to your npm scripts and repeating yourse ...

  2. C++中Reference与Pointer的不同

    Reference与Pointer中直接存储的都是变量的地址, 它们唯一的不同是前者的存储的地址值是只读的, 而后者可以修改. 也就是说Reference不支持以下操作: *a = b 其他语言, 如 ...

  3. variadic templates & pass by const reference & member operator [] in const map & gcc sucks

    /// bugs code with comments #include <iostream> #include <memory> #include <unordered ...

  4. Drupal 7.23:函数module_invoke_all()注释

    /** * Invokes a hook in all enabled modules that implement it. * * All arguments are passed by value ...

  5. 北京地铁换乘算法(二维坐标系,图的深度搜索)开源下载Android源码、性能最优解

    距离2012年11月2日下午2:05:31 已经过去158751270这么多秒了,不小心暴露了我的当前时间. java代码贴出来. private static long gettimelong() ...

  6. 这个拖后腿的“in”

    问题之源 C# 7.2推出了全新的参数修饰符in,据说是能提升一定的性能,官方MSDN文档描述是: Add the in modifier to pass an argument by referen ...

  7. 5.Primitive, Reference, and Value Types

    1.Programming Language Primitive Types primitive types:Any data types the compiler directly supports ...

  8. Python中的passed by assignment与.NET中的passing by reference、passing by value

    Python文档中有一段话: Remember that arguments are passed by assignment in Python. Since assignment just cre ...

  9. CRM 2016 自动保存 Save event arguments

    Save event arguments (client-side reference)   Applies To: Dynamics CRM 2016, Dynamics CRM Online In ...

随机推荐

  1. JMeter学习笔记--JDBC测试计划-连接Mysql

    1.首先要下载jar包,mysql-connector-java-5.1.7-bin.jar 放到Jmeter的lib文件下ext下 2.添加JDBC Connection Configuration ...

  2. PTA列出叶结点 (25分)

    [程序思路] 按从上到下.从左到右的顺序输出,则是层序遍历的顺序,这里需要用到队列.首先需要根据输入找出根节点,将输入利用静态链表的方式保存,没有被指向的编号就是根节点.然后再根据层序遍历遍历树,若该 ...

  3. 1个月连载30个设计模式真实案例(附源码),挑战年薪60W不是梦

    本文所有内容均节选自<设计模式就该这样学> 本文自2012年10月29日起持续连载,请大家持续关注.... 序言 Design Patterns: Elements of Reusable ...

  4. codeforces心得1---747div2

    codeforces心得1---747div2 cf div2的前AB题一般是字符串or数论的找规律结论题 因此标程极为精简 1.小窍门是看样例或者自己打表或造数据找规律 2.一些不确定的操作,可以化 ...

  5. 系统调用篇——SSDT

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  6. Java 获取PDF数字签名证书信息

    PDF文档中可添加数字签名,在添加签名前,需要准备可信任签名证书.对文档中已有的签名,可验证书签是否有效.也可通过一定方法来获取数字签名或者签名证书信息.下面以Java代码示例展示如何读取签名的证书信 ...

  7. 0-pyqt介绍

    1.QT 的特点 2.QT的历史 3.搭建pyQT的开发环境 python  pyqt包  pycharm 4.搭建pyQT第一个应用 必须使用两个类:QApplication和QWidget.都在P ...

  8. [hdu7076]ZYB's kingdom

    不难发现,操作1可以看作如下操作:对于删去$a_{1},a_{2},...,a_{k}$后的每一个连通块(的点集)$V$,令$\forall x\in V,x$的收益加上$s$(其中$s=\sum_{ ...

  9. [luogu4466]和与积

    令$d=\gcd(i,j)$,$i'=\frac{i}{d}$,$j'=\frac{j}{d}$,则$(i',j')=1$,可得$(i'+j',i'j')=1$(假设有公因子$p$,必然有$p|i'或 ...

  10. 快读模板 + #define 压缩for

    快读是一个很重要的模板 #define 压缩for是为了代码的简洁 这里贴一下模板 #define f(i , a , b) for(int i=(a) ; i <= (b) ; i++) us ...