1.dynamic_cast
在多态时,为了让基类指针数组正确地深拷贝,每个基类指针需要知道自己指向的是哪一个派生类;此时用 dynamic_cast < type-id > (expression) 语句可以将基类指针转换为派生类指针,其中 type-id 是派生类,expression是需要被转换的指针;如果转换成功,返回正常cast后的对象指针;如果失败,返回NULL;
实例:
//Circle是Shape的派生类;sample是拷贝构造函数的参数;a是基类指针数组;
for(i=0 ; sample.a[i]!=NULL ; i++)
{
if(dynamic_cast<Circle *>(sample.a[i]))
a[i] = new Circle(*(dynamic_cast<Circle *>(sample.a[i])));
else if(dynamic_cast<Triangle *>(sample.a[i]))
a[i] = new Triangle(*(dynamic_cast<Triangle *>(sample.a[i])));
}
这行代码可以正确地深拷贝;
2.new语句的返回值是什么,如何确定"new xxx"中"xxx"的类型
由于a[i]是基类指针,我们很容易想到:
a[i] = (Shape *)new Circle *(dynamic_cast<Circle *>(sample.a[i]));
然后发现a[i]中的内容,一访问就报错 SIGSEGV, Segmentation fault.(编译不报错)
此处错误在于它会将一个指向Circle对象的指针转换为指向Shape对象的指针,这样做会导致访问a[i]->xxx时出现错误。
而去掉(Shape *)的类型转换之后:
a[i] = new Circle *(dynamic_cast<Circle *>(sample.a[i]));
编译,发现程序报错:[Error] cannot convert 'Circle**' to 'Shape*' in assignment
即此处的a[i]是Shape *型,而new的返回值是Circle **型;证明new的返回值是一个指向new后面这个东西的指针;
因此正确的写法是:
a[i] = new Circle(*(dynamic_cast<Circle *>(sample.a[i])));
这样就不会有问题了;