AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > C++

C++中实现Java的存储管理机制

51自学网 http://www.wanshiok.com

  二、Agent类:用C++指针模拟JAVA对象

  为了更好的说明C++与JAVA的相似之处,笔者建立了Agent类。它通过把一个特定对象类型的指针作为自己的保护成员,来实现对C++指针的包装。

  任何使用Agent类模拟JAVA的程序必须通过如下表所示的方法来使用对象:

  表2

操作JAVA使用Agent后的C++
声明 ObjectClass InstanceAgent<ObjectClass> Instance
创建Instance=new ObjectClass() Instance=new Agent<ObjectClass>
数据访问Instance.Data Instance().Data
方法调用Instance.Method() Instance().Method()
复制 指针复制Instance1=Instance2
内容复制由类自身定义
比较指针比较Instance1==Instance2
内容比较由类自身定义
销毁不需要,由程序内部自动管理

  上表显示了两种对象在使用上的惊人的相似性。本质上,两种对象是一样的,因为JAVA解释器本身就是使用与Agent相似的实现方法。但有些形式上的相似性事实上是无法做到的,因为它们毕竟属于两种不同的语言,必须依照各自的规定。以下是两种需要注意的形式上的差别:在C++中,

  1、 象所属类的名称(如ObjectClass)必须放在Agent后,用〈 〉包括起来(否则,该类将与本文所讨论的Agent类毫无关系);

  2、 对象本身数据的访问和方法的调用必须在对象表识符后加一对括号,如Instance().Method(),因为Agent重定义了操作符operator (),以帮助编译器将一个Agent的实例(如Instance)解释成用户所使用的具体某一个类(如ObjectClass)的实例,而Instance().Method()这一调用本身也等价于((ObjectClass&)Instance).Method()。

  另外,任一使用了Agent的程序必须在首部加入#include "Agent.h"才能实现对它的访问。

  以下为包含类Agent全部定义的C++头文件。由于该文件篇幅较小,所有Agent的方法均采用内联函数的形式定义。

#ifndef OBJECT_AGENT_CLASS
#define OBJECT_AGENT_CLASS

#define null 0

template<class ObjectType>
class Agent
{
int *Reference;
static bool bNewOperation;

protected:

ObjectType *Marrow;
void Finalize()
{
if (Reference)
{
(*Reference)--;
if (Marrow)
{
if (*Reference<=0 && Marrow)
{
delete Marrow;
delete Reference;
}
Marrow=null;
}
Reference=null;
}
}

public:

// constructors
Agent()
{
if (bNewOperation)
{
Marrow=new ObjectType;
Reference=new int;
*Reference=1;
bNewOperation=false;
}
else
{
Marrow=null;
Reference=null;
}
}

Agent(ObjectType obj)
{
Marrow=new ObjectType;
Reference=new int;
*Reference=1;
*Marrow=obj;
}

// destructor
~Agent() { Finalize(); }

// convertions
operator ObjectType&() { return *Marrow; }

// operators
Agent<ObjectType>& operator=(Agent<ObjectType> obj)
{
Finalize();
Marrow=obj.Marrow;
Reference=obj.Reference;
(*Reference)++;
return *this;
}

Agent<ObjectType>& operator=(Agent<ObjectType>* obj)
{
Finalize();
if (obj)
{
Marrow=obj->Marrow;
Reference=obj->Reference;
}
return *this;
}

bool operator ==(Agent<ObjectType> obj) const
{
return Marrow==obj.Marrow;
}

bool operator !=(Agent<ObjectType> obj) const
{
return Marrow!=obj.Marrow;
}

ObjectType& operator ()() { return *Marrow; }

void *operator new(size_t size)
{
bNewOperation=true;
return new char[size];
}
};

template<class ObjectType> bool Agent<ObjectType>::bNewOperation=false;

#endif

  从源程序中可以看出,Agent类实际上是一个模版(template)。这样做的好处是,用户不必为包容自己不同类型的对象而定义之相对应的Agent类。

  Agent类的工作原理是这样的:

  当用户使用Agent<ObjectClass>来定义对象的类型时,他事实上定义的是一个Agent类型的对象。编译器自动为该对象产生一个类型为ObjectClass*,名为Marrow的成员,而ObjectClass* Agent::Marrow才真正代表用户将要建立的对象。整型成员Reference记录当前对此对象的Marrow的引用个数,当降为0时自动消除Marrow,即销毁用户定义的ObjectClass实例。当用户调用Instance=new Agent<ObjectClass>来创建对象时,分配Marrow,Reference置1,对象处于可使用状态。两个Agent实例互相赋值时,重定义的操作符operator =协助复制Marrow指针,更改公共的Reference成员,使之指示正确的引用计数。还有一个必须注意的静态成员:bNewOperation。它是一个布尔(真假值)类型的变量。当程序员用Agent<ObjectClass> Instance来定义对象时,其值为false,指出不需要真正建立Agent::Marrow的实例,因而Marrow将被赋值为null;当用Instance=new Agent<ObjectClass>来创建对象实例时,其值为true,提示构造函数建立相应Marrow的实例。其控制通过操作符operator new实现。而操作符operator ()则使得,当调用Instance()时,编译器自动返回ObjectClass类型的*Marrow,所以调用用户所需的对象成员可以使用Instance().Data和Instance().Method()。

 
 

上一篇:Linux上搭建C/C++IDE开发环境  下一篇:C++应用程序中创建持久对象