这两种方式没有差别,C++中也支持这两种方式,但是和C++中的强制类型转换运算符对比,不太容易识别,作用范围不细化。所以,C++中就有了const_cast、dynamic_cast、reinterpret_cast和static_cast四个强制类型转换运算符
见https://blog.csdn.net/Master_Cui/article/details/106391914
2、static_cast的注意事项
class base
{
public:
base():data(0){cout<<__func__<<endl;}
~base(){cout<<__func__<<endl;}
void func(){
cout<<"func in base"<<endl;
data=10;
}
int data;
};
class derive:public base
{
public:
derive(){cout<<__func__<<endl;}
~derive(){cout<<__func__<<endl;}
void func() {
cout<<"func in derive"<<endl;
static_cast<base>(*this).func();
cout<<base::data<<endl;
}
};
int main(int argc, char const *argv[])
{
derive d;
d.func();
}
根据输出结果可以看到,调用子类中的func后,基类中的data的值并没有发生变化,原因是因为static_cast<base>(*this)产生的只是个this的临时变量,当调用完func后,临时变量被释放,修改的也只是this临时对象中的data,所以this中的data数据不变
2.1、解决办法有两种
2.1.1、修改L20
static_cast<base&>(*this)
dynamic_cast<base&>(*this)
上述两种修改方式都可以
2.1.2、直接指定作用域调用基类中的func
base::func()
两种办法的最终输出结果如下
3、dynamic_cast
见https://blog.csdn.net/Master_Cui/article/details/110520918
4、reinterpret_cast
reinterpret_cast是强制类型转换符用来处理无关类型转换的。比如任意类型的指针或引用之间的转换,指针和int型之间的转换,int到指针的转换。
long Hash(void *p) {
long val = reinterpret_cast<long>(p);
return val ^ (val >> 16);
}
int main(int argc, char const *argv[])
{
int a[5];
for (int i=0;i<5;++i) {
cout<<Hash(a+i)<<endl;
}
}
注意,上述代码中的hash函数的返回值以及val的类型的sizeof必须和指针的sizeof一样,否则会导致指针的字节数缩窄,无法编译通过
64位系统指针的字节数是8,32为系统指针的字节数是4,所以,使用了reinterpret_cast的代码不可移植
十六、对于get接口,不要返回对象private和protected数据的指针、引用和迭代器
自定义一个类时,类可能会有很多private和protected的成员,外部如果想访问这些内部的数据,那么就需要通过类提供的public的get接口来访问,get接口的返回值一般是按值返回,如果按引用返回或者返回一个指针,那么外部的使用者就可以对内部的数据成员进行修改,会破坏private和protected的封装性。
但是并不使所有的接口都不能返回内部数据的指针或引用,如果真的需要返回一个内部数据成员的指针或者引用,那么需要添加一个底层const
具体示例见https://blog.csdn.net/Master_Cui/article/details/112624465、https://blog.csdn.net/Master_Cui/article/details/113001297
参考
《Effective C++》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出