在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. SpringBoot2.x请求注解简单介绍(4)

    1.新建项目,项目中实战讲解注解作用 2.pom.xml依赖配置 <properties> <project.build.sourceEncoding>UTF-8</pr ...

  2. 攻防世界 WEB 高手进阶区 tinyctf-2014 NaNNaNNaNNaN-Batman Writeup

    攻防世界 WEB 高手进阶区 tinyctf-2014 NaNNaNNaNNaN-Batman Writeup 题目介绍 题目考点 了解js代码(eval函数.splice函数) 了解正则 Write ...

  3. C++ substr 的两个用法

    substr是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度.   basic_string substr(size_type _Off = 0,size_type _C ...

  4. js实现全选与全部取消功能

    function checkAll() { //把所有参与选择的checkbox使用相同的name,这里为"num_iid"    var eles = document.getE ...

  5. 『学了就忘』Linux软件包管理 — 47、Linux源码包的安装和卸载

    目录 1.源码包安装服务的注意事项 2.源码包安装服务的过程 3.源码包安装服务的删除 4.源码包安装服务的启动 5.源码包安装服务的关闭 1.源码包安装服务的注意事项 (1)安装服务选择哪种软件包? ...

  6. 96-00年CPU功耗感知调度研究

    最近读了一些1996-2000年的通过调度来降低cpu能耗的文章,主要文章有[1] [2] [3] [4] [5], 简单总结一些该时期单核CPU功耗感知的调度策略. 该时期还出现了很多关于低功耗电路 ...

  7. [cf1361E]James and the Chase

    称一个点是"好点",当且仅当其到其余所有点恰存在一条简单路径 结论1:$x$为好点当且仅当以$x$为根的dfs树包含所有点且非树边均为返祖边 若不包含所有点,那么$x$到不被包含的 ...

  8. Sentry 监控 - Snuba 数据中台架构(编写和测试 Snuba 查询)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  9. AT2558 [ARC073D] Many Moves

    开始被标签带骗了. 考虑一个\(dp\),\(f[i][j]\)代表有一个棋子在\(x_i\),另外一个\(j\)的最小答案. 那么考虑转移. 如果\(j != x_{i - 1}\) 那么答案自然贡 ...

  10. Codeforces 1089I - Interval-Free Permutations(析合树计数)

    Codeforces 题面传送门 & 洛谷题面传送门 首先题目中涉及排列的 interval,因此可以想到析合树.由于本蒟蒻太菜了以至于没有听过这种神仙黑科技,因此简单介绍一下这种数据结构:我 ...