最近一直在写一个将 Jar文件转换到 C++源文件的程序。关于如何实现 JAVA类体系一直迷茫了好久,一开始想用模板实现各个类的智能指针。写了之后才发现该方法行不通。该方法思路大致在如下代码中。
class Object { }; class String : public Object { }; template<typename T> class smart_ptr { public: smart_ptr(T* p) { } }; smart_ptr<Object> o = new String();
但是如下代码就无法编译通过。
smart_ptr<String> s = new String(); smart_ptr<Object> o = s;
除非在给 smart_ptr添加一个可以接受其它参数的构造函数。
template<typename T2> smart_ptr(smart_ptr<T2> *p) { }
但是接下来有碰到了一系列问题,包括如何 实现数组的处理 。 smart_ptr做的越来越复杂,实在是没法看了。Google了一把之后发现有一个库 DFC( DObject Foundation Class Library)。
DFC库意在用 C++实现一个 JAVA的类库( JDK),然后通过 java2cpp把 JAVA程序(不包含 JDK),将这两部分合起来就是一个完整的 C++程序。 DFC包含的特性有,运行时类型信息,多线程,图形接口( awt), SQL接口。由于 DFC希望实现整个 JDK,而 JDK又是异常复杂而庞大,所以 DFC做的不是特别成功。目前也不是非常活跃。但是读一下分析一下设计思想还是可以的嘛 。
DFC可以从SourceForge上下载,网址为http://sourceforge.net/projects/dfc/。
下面是读了 DFC之后的关于类继承体系的一些理解。
DFC的类体系包含了 四组类。 通过这四组类之间的相互关系实现了JAVA的类体系。这样实现的类体系虽然类的数目比较多,但整体结构还比较清晰,智能指针的实现也比较简单。
第一组类对应到 JAVA类。如 Object、 String、 Class等。它们之间的继承关系和 JAVA的继承基本一致。下面的图列了几个类的关系。DObject是这些类的基类,该组的所有其它类包括JAVA中的接口都继承自DObject。
第二组为 智能指针类。每个JAVA类都有一个对应的指针类。下面的图列了几个类的关系。DObjectPtr是这些类的基类, 该组的所有其它类都继承自DObject Ptr。DObjectPtr包含一个DObject的指针,其它继承类也使用该指针来存储真正的对象。
第三组为 是数组类。DFC目前实现了一维数组和二维数组。DObjectArray是该组所有其它类的基类。DObjectArray又派生自DObject。
第四组为 数组的智能指针类。DObjectArrayPtr是该组所有其它类的基类,DObjectArrayPtr派生自DObjectPtr。
下图为这四组类之间的整体关系。该体系中有两个基类DObject和DObjectPtr,其它类直接或间接的继承自这两个类。
void testDerive() { // 调用 DObjectPtr::DObjectPtr(DObject* p= 0) DObjectPtr object = new DObject(); // 调用 DStringPtr::DStringPtr(DObject* p= 0) DStringPtr string = new DString(); // 调用 const DObjectPtr& DObjectPtr::operator=(const DObjectPtr& r) object = string; // 调用 DObjectPtr::DObjectPtr(DObject* p= 0) DObjectPtr object2 = new DString(); // 调用 DObjectPtr::operator DObject*() // DStringPtr::DStringPtr(DObject* p= 0) DStringPtr string2 = (DStringPtr) object2; }
void testArray() { // 调用 DObjectArrayPtr::DObjectArrayPtr(DObject* p= 0) DObjectArrayPtr objectArray = new DObjectArray(2); // 依次调用 DObjectPtr& DObjectArrayPtr::operator[](int index) // const DObjectPtr& DObjectPtr::operator=(DObject* p) objectArray[0] = new DObject(); // 依次调用 DObjectPtr& operator[](int index) // DObjectPtr::operator DObject*() // DObjectPtr::DObjectPtr(DObject* p= 0) DObjectPtr object = objectArray[0]; DStringPtr string = objectArray[1]; }
void testArray2d() { // 调用 DObjectArray2dPtr::DObjectArray2dPtr(DObject* p= 0) DObjectArray2dPtr objectArray = new DStringArray2d(2, 2); // 依次调用 DObjectArrayPtr& DObjectArray2dPtr::operator[](int index) // DObjectPtr::operator DObject*() // DObjectArrayPtr::DObjectArrayPtr(DObject* p= 0) DObjectArrayPtr array0 = objectArray[0]; // 依次调用 DObjectPtr& DObjectArrayPtr::operator[](int index) // const DObjectPtr& DObjectPtr::operator=(DObject* p) array0[0] = new DString("Test String Array 2D"); // 依次调用 DObjectPtr& DObjectArrayPtr::operator[](int index) // DObjectPtr::operator DObject*() // DObjectPtr::DObjectPtr(DObject* p= 0) DObjectPtr object0 = array0[0]; // 依次调用 DObjectArrayPtr& DObjectArray2dPtr::operator[](int index)' // DObjectPtr& DObjectArrayPtr::operator[](int index) // DObjectPtr::operator DObject*() // DObjectPtr::DObjectPtr(DObject* p= 0) DObjectPtr object = objectArray[0][0]; }