高产似母猪?-_-||,感觉毕竟都是比较基础的东西,所以个人 觉得每天把自己掌握的一些以前漏掉的或者了解的不够的总结下,下次面试的时候也可以翻一翻。PS:2021-10-27发现理解有问题,后面再理解理解再继续
const_cast转换符是用来移除变量的const或volatile限定符,后面这个我还没了解到,后面有机会再补上,所以我只来说const方面的内容,用const_cast来去除const限定,就字面意思咯,但是好像不推荐使用,用我自己的话理解就是把一个是不能再变化的数据强转为可以变化的数据,暂时这么理解,有新的理解后面再改。
dynamic_cast的用法就是把一个基类的指针强转为子类的指针,有几个注意事项,看下面的代码。
class Base
{
private:
/* data */
public:
Base(/* args */);
virtual ~Base(); //必须要有一个虚函数要不然编译器不让编译过
};
Base::Base(/* args */)
{
}
Base::~Base()
{
}
class derived:public Base
{
private:
/* data */
public:
void virtual name();
derived(/* args */);
virtual ~derived();
};
derived::derived(/* args */)
{
}
derived::~derived()
{
}
void derived::name(/* args */)
{
std::cout << "derived name"<< std::endl;
}
int main()
{
Base *baseA = new Base;
if(derived *d = dynamic_cast<derived*> (baseA)){
std::cout << "dynamic_cast successful"<< std::endl;
}else{
std::cout << "dynamic_cast fail"<< std::endl;//看下面的输出结果就知道了,这样子是转换不成功的
}
Base *baseB = new derived;
if(derived *d = dynamic_cast<derived*> (baseB)){
std::cout << "dynamic_cast successful"<< std::endl;
}
Base baseC;
derived &d = dynamic_cast<derived&>(baseC);/强转引用的话会直接崩溃
return 0;
}
上面的代码输出内容:
从结果看,dynamic_cast在运行时是有进行类型检查的,这也是dynamic_cast相对于 static_cast,reinterpret_cast来说安全的地方,他会保障数据的安全,但同时也会有一定的性能损耗。在这个点上有的人觉得数据安全比较重要,出可以防止奇奇怪怪的bug出现,毕竟虽然性能有一定的损耗但是还是在可以接受的范围内,这个就仁者见仁智者见智了。
知识点:
为啥编译不过,
1、必须要有虚函数才可以转换。
2、只能处理转换指针或引用,不能转换对象。
3、只能识别多态数据类型,转换失败就是null
多态,父类指针可以根据多态转化为子类指针
子类指针存储一个父类指针,转换失败。指针为 00000
子类指针转换成父类,自动转换。
static_cast 用于进行比较“自然”和低风险的转换,如整型和浮点型、字符型之间的互相转换。static_cast 不能用于在不同类型的指针之间互相转换,也不能用于整型和指针之间的互相转换,当然也不能用于不同类型的引用之间的转换。因为这些属于风险比较高的转换。
reinterpret_cast 用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作。这种转换提供了很强的灵活性,但转换的安全性只能由程序员的细心来保证了。