c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法
- 序列化
1、序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。 2、什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候; b)当你想用套接字在网络上传送对象的时候; c)当你想通过RMI传输对象的时候; 3、当对一个对象实现序列化时,究竟发生了什么? 在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如: Foo myFoo = new Foo(); myFoo .setWidth(37); myFoo.setHeight(70); 当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。 FileOutputStream fs = new FileOutputStream("foo.ser"); ObjectOutputStream os = new ObjectOutputStream(fs); os.writeObject(myFoo);
虚拟继承:
C++虚继承可以防止多重继承产生的二义性问题。
虚继承,就是在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类,如下面代码中的base类。虚继承在多重继承的时可以防止二义性。
class base
class derived1 : virutal public base
class derived2 : virtual public base
class derived3 : public derived1, public derived2
以上的代码如果用到了base中的某个成员变量就不会产生二义性。和#progma once在头文件中的作用类似。请看下面的例子:
#include <iostream>
using namespace std;
class Parent
{
public:
int p; // p将会被所有的子类继承,也将是二义性的根源
inline Parent()
{
p = 10;
}
};
class Child1 : public Parent
{
public:
int c1;
inline Child1()
{
p = 12; // p在子类Child1中被赋值为12
c1 = 12;
}
};
class Child2 : public Parent
{
public:
int c2;
inline Child2()
{
p = 13; // p在子类Child2中被赋值为13
c2 = 13;
}
};
class GrandChild : public Child1, public Child2
{
public:
int grandchild;
// p显然也存在于GrandChild中,但是到底是12,还是13呢?这就产生了二义性
inline GrandChild()
{
grandchild = 14;
}
};
int main(void)
{
GrandChild* pGC = new GrandChild();
cout << pGC->p << endl;
return 0;
}
上面程序是不能通过编译的,编译器输出的错误信息如下:
…: error C2385: 'GrandChild::p' is ambiguous
…: warning C4385: could be the 'p' in base 'Parent' of base 'Child1' of class 'GrandChild'
…: warning C4385: or the 'p' in base 'Parent' of base 'Child2' of class 'GrandChild'
正如编译器告诉我们的那 样,GrandChild::p是模棱两可,它被Child1继承了即Child1中包含了一个Parent subobject,也被Child2继承了即Child2中也包含了一个Parent suboject,然后GrandChild又同时继承了Child1和Child2,根据“derived class中要保持base class的完整原样性原则”,因此GrandChild包含了两个ParentObject。所以当pGC->p时,编译器根本无法确定是调用Child1::p还是Child2::p,由此边产生了模棱两可的情形。怎么解决这样的问题呢?答案就是用虚继承或者叫虚基类的方式。
在上面的示例程序中做如下改动:
class Child1 : public Parent -> class Child1 : virtual public Parent