• 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 
    ";
    10     }
    11 };
    12  
    13  
    14 class derived: public base 
    15 {
    16 public:
    17     void show() 
    18     {
    19         cout<<"In derived 
    ";
    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

     

     

       

  • 相关阅读:
    深入理解Java:注解(Annotation)--注解处理器
    Java进阶之reflection(反射机制)——反射概念与基础
    JAVA 动态代理
    注解是建立在class文件基础上的东西,同C语言的宏有异曲同工的效果
    Android 进阶8:进程通信之 Binder 机制浅析
    Android Binder机制(一) Binder的设计和框架
    Android Service初解
    原生sql和 TP sql怎么关联?
    Laravel 修改默认日志文件名称和位置
    laravel asset()函数
  • 原文地址:https://www.cnblogs.com/iloveyouforever/p/3442306.html
Copyright © 2020-2023  润新知