在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. 【解决方案】Pyinstaller打包exe策略(简单实用)

    场景说明 在业务场景中, 经常需要Python开发一些小程序/脚本/GUI界面,进行简单的项目测试或未安装Python 的小伙伴们使用. 使用Pyinstaller将Python脚本或者项目打包,生成 ...

  2. go条件语句

    1. if else package main import "fmt" func main(){ a :=123 if a>100{ fmt.prinln("大于 ...

  3. 个人网站迁移之旅:从博客到知识库,从 Hexo 到 Docusaurus

    或是出于跟风,或是为了简历能好看点,2020 年 2 月,在翻看了中文互联网大量的「免费个人网页搭建教程」后,我选择了 Hexo + Github Pages 的方案,找了一款看上去还不错的主题,搭建 ...

  4. 使用Typora+PicGo配置Gitee图床

    1.图床痛点 通常我们用 Typora 写 Markdown 文档,对于文档里面的图片,如果不使用图床,图片都是存放在本地,如果把文档复制到别的地方,还得额外复制图片,特别麻烦. 为了解决这种问题,一 ...

  5. python及pygame雷霆战机游戏项目实战01 控制飞机

    入门 在这个系列中,将制作一个雷霆战机游戏. 首先,将游戏设置修改一下: WIDTH = 480 HEIGHT = 600 FPS = 60 玩家精灵 要添加的第一件事是代表玩家的精灵.最终,这将是一 ...

  6. Django 小实例S1 简易学生选课管理系统 总目录

    python Django实现的一个简易的教务选课系统. 介绍与演示的视频版本已发到我的b站: https://www.bilibili.com/video/BV1er4y1w7ty. 项目已上传到我 ...

  7. 1组-Alpha冲刺-1/6

    一.基本情况 队名:震震带着六菜鸟 组长博客:https://www.cnblogs.com/Klein-Wang/p/15526531.html 小组人数:7人 二.冲刺概况汇报 王业震 过去两天完 ...

  8. python接口之request测试:以json格式发送post请求,.json方法,查看响应结果的情况

    json和dict python中的dict类型要转换为json格式的数据需要用到json库: import json <json> = json.dumps(<dict>) ...

  9. [bzoj5462]新家

    先离线,将询问按照时间排序,维护商店出现和消失 对于每一个询问,先二分枚举答案,假设是ans, 即要求对于区间[l-ans,l+ans],商店的种类数是k(l是询问的位置) (当然需要先将所有位置离散 ...

  10. [atARC111F]Do you like query problems

    (以下修改指1和2类操作,询问指3类操作,操作指修改或询问) 注意到总方案数确定,那么不妨求出答案的期望,再乘上方案数即为答案 (这里从期望的角度考虑只是为了描述方便,并没有太大的实际意义) 设$E( ...