之前c++,最近java有点混乱,总结一下:
1.在写java程序的时候会发现,假如你自己写了一个类class A{。。。},这个时候你要实例化,必须new一个;但是在c++里面就不用,c++中你可以直接声明A a;
为何:
a.java里面所有变量都是引用(除了基本类型),引用就相当于一个指针,因此你必须要new,不然没法使用;当然在c++里面,指针可以光声明,扔在那里不new,你用的时候还是要new的,java编译器在安全方面做出了优化。
b.c++里面,A a;这句运行时,会自动调用默认构造函数,给你构造一个出来,这是一个实例对象,不是引用,A中的field是有值的,不过这个值可能是一个你不想要的。
2.关于RTTI的实现机制,java跟c++是不同的,但原理是一样的:
a.java如果实现RTTI,很简单,java的每个类都生成一个class文件。比如现在有一个基类shape,其子类有circle,square等。有一个vector i,在java中,vector如果没有被泛型化,可以放入任何object。这时你可以把circle,square都放进去,upcasting。取出来的时候,需要downcasting回shape,比如(shape)i[0],这时在java中会进行RTTI,但是这种括号形式的造型,在c++中不会进行RTTI,只会被强制转换为()中类型。那RTTI如何进行呢,因为每个类都是一个class,被加载到内存中后,字节码是不同的,因此可以方便进行RTTI。
b.c++中,也有RTTI,在dynamic_cast跟typeid中进行。很容易推测,要进行RTTI就要需要知道类的信息,在java中有Class类记录类型信息,其实在c++中也有type_info,(个人认为这两个东西,本质上是一样的),只是很少人用到。因此,在c++中,RTTI的进行依据是type_info。
c.别的还木有看,只看了dynamic_cast的运作原理:dynamic_cast是类型转换,upcast比较好理解,但downcast,这里如何操作的呢?当类中存在虚函数时,编译器就会在类的成员变量中添加一个指向虚函数表的vptr指针,每一个class所关联的type_info object也经由virtual table被指出来,通常这个type_info object放在表格的第一个slot。当我们进行dynamic_cast时,编译器会帮我们进行语法检查。如果指针的静态类型和目标类型相同,那么就什么事情都不做;否则,首先对指针进行调整,使得它指向vftable,并将其和调整之后的指针、调整的偏移量、静态类型以及目标类型传递给内部函数。其中最后一个参数指明转换的是指针还是引用。两者唯一的区别是,如果转换失败,前者返回NULL,后者抛出bad_cast异常。