类对象的“传值”与“传引用”

原创 2012年03月25日 21:55:23

   "传值"就是通过值来传递一个对象,这个过程需要拷贝构造函数来进行。而"传引用"实质上就是一种指针传递。两种传递方式在使用上存在效率问题和"切割"问题。

 

   1、效率

   而前所述,"传值"需要调用拷贝构造函数。例如:

   class CTest
   {
   public:
       CTest()
       {
           cout << "CTest::CTest()" << endl;
       }

       CTest(const CTest& ref)
       {
           cout << "CTest::CTest(const CTest& ref)" << endl;
       }

       ~CTest()
       {
           cout << "CTest::~CTest()" << endl;
       }

       CTest fun(CTest obj)
       {
           return obj;
       }
   };

 

   void main()
   {
       CTest Obj, obj1;

       CTest obj2 = obj.fun(obj1);
   }

   上述代码的输出结果是:

   CTest::CTest()

   CTest::CTest()

   CTest::CTest(const CTest& ref)

   CTest::CTest(const CTest& ref)

   CTest::~CTest()

   CTest::~CTest()

   CTest::~CTest()

   CTest::~CTest()

   在调用fun()成员函数时,传入实参调用一次拷贝构造函数,返回值调用一次拷贝构造函数。也就是说:调用一次fun()成员函数,需要调用两次拷贝构造函数和两次析构函数。如此昂贵的开销不得不让人有所警惕。

   定义一个对象的引用就是给对象起个别名,无需调用拷贝构造函数。因而,将fun()成员函数的形参和返回值改为"传引用",能避免调用拷贝构造函数和析构函数。这社会,能节省开销就要节省开销。

   *注:在上述例子中,将返回值改为"传引用"只是为了说明问题,其实返回局部对象的引用,其后果是难以预测的。

 

   2、切割问题

   当一个派生类的对象作为基类对象被传递时,它(派生类对象)的作为派生类所具有的行为特性会被“切割”掉,从而变成了一个简单的基类对象。例如:

   class CBase

   {

   public:

      virtual void Display()

      {

          cout << "CBase::Display()" << endl;

      }

   };

 

   class CDerive : public CBase

   {

   public:

       virtual void Display()

       {

           cout << "CDerive::Display()" << endl;

       }

   };

 

   void fun(CBase ObjCBase)

   {

       ObjCBase.Diaplay();

   }

 

   这时,如果执行下面语句:

   CDerive ObjCDerive;

   fun(ObjCDerive);

   很抱歉,这时执行的是CBase::Display()。这就是切割问题。其实也不难理解:fun()申请的是CBase对象的空间BUF1,这时跑来的却是CDerive对象的空间BUF2,BUF1可装不下BUF2,不好意思,BUF2中除BUF1以外的空间必须切割掉。这种切割问题很明显违反了程序员的意图。

   如果将fun()的形参改为"传引用",问题就回到多态性上了。"传引用"实质就是一种地址传递,这时候基类的指针指向派生类,因而调用的虚函数就是派生类的虚函数。这时程序员的意图得到了表达。

Java传递基本类型:值传递,对象作为参数:引用传递

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。 引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相...
  • dreamxiaowei
  • dreamxiaowei
  • 2017年02月25日 15:53
  • 2914

关于Java对象作为参数传递是传值还是传引用的问题

前言  在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引...
  • xiangwanpeng
  • xiangwanpeng
  • 2016年09月06日 22:37
  • 2166

jsp将实体类作为参数传到action(或者叫controller)

$(document).ready(function(){ //添加 $("#add_button").click(function() { $("#form1").submit();...
  • xb12369
  • xb12369
  • 2014年07月30日 15:00
  • 7811

Intent传值 与 传递类对象

Intent 传递类 Parcelable encountered IOException writing serializable object (name = xxx)
  • qq_36029400
  • qq_36029400
  • 2016年11月04日 21:25
  • 149

关于Java对象作为参数传递是传值还是传引用的问题

前言  在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引...
  • xiangwanpeng
  • xiangwanpeng
  • 2016年09月06日 22:37
  • 2166

Java中方法调用参数传递的方式是传值,尽管传的是引用的值而不是对象的值。(Does Java pass by reference or pass by value?)

原文地址:http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html 在Java中,所有的对象变量都是引用,Java...
  • jubincn
  • jubincn
  • 2012年02月03日 22:56
  • 4052

父类引用指向子类对象属性值

父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。 Animal animal = new...
  • xingxiupaioxue
  • xingxiupaioxue
  • 2017年04月13日 00:51
  • 781

父类引用指向子类对象

  • 2012年11月24日 15:59
  • 3KB
  • 下载

java多态性详解——父类引用子类对象

  • 2012年05月01日 17:45
  • 38KB
  • 下载

动态创建控件,使用类对象管理并获取控件的值

  • 2015年11月01日 23:02
  • 38KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:类对象的“传值”与“传引用”
举报原因:
原因补充:

(最多只允许输入30个字)