When do we pass arguments by reference or pointer?
在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?的更多相关文章
- [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 ...
- C++中Reference与Pointer的不同
Reference与Pointer中直接存储的都是变量的地址, 它们唯一的不同是前者的存储的地址值是只读的, 而后者可以修改. 也就是说Reference不支持以下操作: *a = b 其他语言, 如 ...
- variadic templates & pass by const reference & member operator [] in const map & gcc sucks
/// bugs code with comments #include <iostream> #include <memory> #include <unordered ...
- Drupal 7.23:函数module_invoke_all()注释
/** * Invokes a hook in all enabled modules that implement it. * * All arguments are passed by value ...
- 北京地铁换乘算法(二维坐标系,图的深度搜索)开源下载Android源码、性能最优解
距离2012年11月2日下午2:05:31 已经过去158751270这么多秒了,不小心暴露了我的当前时间. java代码贴出来. private static long gettimelong() ...
- 这个拖后腿的“in”
问题之源 C# 7.2推出了全新的参数修饰符in,据说是能提升一定的性能,官方MSDN文档描述是: Add the in modifier to pass an argument by referen ...
- 5.Primitive, Reference, and Value Types
1.Programming Language Primitive Types primitive types:Any data types the compiler directly supports ...
- 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 ...
- CRM 2016 自动保存 Save event arguments
Save event arguments (client-side reference) Applies To: Dynamics CRM 2016, Dynamics CRM Online In ...
随机推荐
- git stash 存储命令
应用场景 一.当你接到一个修复紧急 bug 的任务时候,一般都是先创建一个新的 bug 分支来修复它,然后合并,最后删除.但是,如果当前你正在开发功能中,短时间还无法完成,无法直接提交到仓库,这时候可 ...
- k3s单机版安装部署 附一键安装脚本
作者:SRE运维博客 博客地址: https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/211109907029/ 相关话题:https://ww ...
- PTA7-1 根据后序和中序遍历输出先序遍历
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. 输入格式: 第一行给出正整数N(≤30),是树中结点的个数.随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果, ...
- Django 小实例S1 简易学生选课管理系统 3 创建用户模型(model)
Django 小实例S1 简易学生选课管理系统 第3节--创建用户模型(model) 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新 ...
- 麒麟Linux上编译subversion
麒麟Linux上编译subversion svn-1.7不支持svn info --show-item=revision[1]获取revision. svn-1.12开始不能保存密码stackover ...
- Ultraedit和写字板修改Tomcat 6.0的server.xml不生效
转:http://blog.csdn.net/greencacti/article/details/6615321 本人在修改Tomcat 6.0的server.xml的时候,发现写字板修改完保存的时 ...
- [loj2339]通道
类似于[loj2553] 对第一棵树边分治,对第二棵树建立虚树,并根据直径合并的性质来处理第三棵树(另外在第三棵树中计算距离需要使用dfs序+ST表做到$o(1)$优化) 总复杂度为$o(n\log^ ...
- [cf787E]Till I Collapse
考虑对询问分块,对于i<K的询问,暴力处理,时间复杂度为o(Kn):对于i>K的询问,发现答案都小于n/K且满足单调性,那么可以二分出每一段相同的答案,时间复杂度为$o(n^{2}log_ ...
- 【HTML】标签
HTML标签 2020-09-08 15:37:37 by冲冲 1. 标签 <!DOCTYPE html> <html> <head> <meta cha ...
- Collections集合工具类的常用方法
Collections集合工具类的方法 addAll与shuffle import java.util.ArrayList; import java.util.Collections; /* - ja ...