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

原创 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()的形参改为"传引用",问题就回到多态性上了。"传引用"实质就是一种地址传递,这时候基类的指针指向派生类,因而调用的虚函数就是派生类的虚函数。这时程序员的意图得到了表达。

相关文章推荐

delphi 函数参数传递 默认参数(传值)、var(传址)、out(输出)、const(常数)四类

参数可以分为: 默认参数(传值)、var(传址)、out(输出)、const(常数)四类 {默认参数是传值, 不会被改变}function MyF1(x: Integer): Integer;begi...
  • rznice
  • rznice
  • 2011年11月11日 15:27
  • 9470

java方法传值还是传引用的问题

java方法传值还是传引用问题

Intent传值 与 传递类对象

Intent 传递类 Parcelable encountered IOException writing serializable object (name = xxx)

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

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

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
  • 3845

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

父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。 Animal animal = new...

父类引用指向子类对象

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

Java中一些基本概念详解:栈、堆、对象大小、引用、传值(转)

java基本概览

android activityIntent 传值 传对象

  • 2015年04月10日 09:42
  • 1.27MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:类对象的“传值”与“传引用”
举报原因:
原因补充:

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