C++ 强制类型转换 static_cast、dynamic_cast、const_cast、reinterpret_cast
文章目录
一.const_cast
将const修饰的变量强制转换成没有const修饰,也就是消除const属性
void test1()
{
const int MAX = 5;
const int *p = &MAX;
//*p = 10;//ERROR, const 修饰在*前,不能改变值
int *q = const_cast<int *>(p);
*q = 10;
//也可以直接这样修改
//*(const_cast<int*>(p)) = 10;
cout << *p << endl;
cout << *q << endl;
cout << MAX << endl;
}
二.static_cast
也就是我们所说的静态转换,编译器中两个完全不相干的类,如
B *b = new B();
A *a = (A*)b;
也不会报错,但是会留下安全隐患,我们如果使用static_cast就可以避免隐患,让编译器直接报错
class A
{
private:
char *_ptr;
};
class B
{
private:
int _i;
};
void test2()
{
B *b = new B();
A *a = (A *)b;//并不会报错,但是会留下安全隐患
//A *a = static_cast<A*>(b);//会直接报错
}
三.reinterpret_cast
与普通的强制转换相同,用的比较少。
void test3(){
float d = 2.5;
float *pd = &d;
// int *pi = (int*)pd;//与下面的强制转换相同
int *pi = reinterpret_cast<int*>(pd);
cout << *pd << " " << *pi << endl;
}
四.dynamic_cast
RTTI:runtime type identification 运行时类型识别
C++原本是静态语言,在这里实现动态联编,需要了解 typeinfo ;dynamic_cast类型强制转换和它密切相关
1.typeinfo头文件的使用
class A1
{
};
class B1 : public A1
{
};
class A2
{
public:
virtual void func() {}
};
class B2 : public A2
{
};
void test1()
{
//1.普通类型
cout << ((typeid(int) == typeid(char *)) ? "true" : "false") << endl;
cout << ((typeid(char *) == typeid(char *)) ? "true" : "false") << endl;
//2.没有虚函数的派生
A1 *pa = new B1();
cout << "typeid(*pa).name() = " << typeid(*pa).name() << endl;
cout << "A1 VS *pa:" << ((typeid(*pa) == typeid(A1)) ? "true" : "false") << endl;
//B1 *b1 = dynamic_cast<B1*>(pa);//ERROR!注意,dynamic_cast只有在存在虚函数的情况下才能够使用
//3.有虚函数的派生
A2 *pa2 = new B2();
cout << "typeid(*pa2).name() = " << typeid(*pa2).name() << endl;
cout << "A2 VS *pa2:" << ((typeid(*pa2) == typeid(A2)) ? "true" : "false") << endl;
}
2.dynamic_cast的使用
注意RTTI 与 dynamic_cast只能用在包含了虚函数的类中,也就是多态的机制中。
dynamic_cast的转换更为安全,将一个指向派生类的基类指针,重新强制转换为派生类指针,成功转换返回true, 转换失败返回false;
void test2()
{
//1.没有虚函数的情况下
B1 *b1 = new B1();
A1 *a1 = dynamic_cast<A1 *>(b1);
if (a1)
{
cout << "转换成功" << endl;
}
else
{
cout << "转换失败" << endl;
}
//2.有虚函数
A2 *a2 = new B2();
B2 *b2 = dynamic_cast<B2 *>(a2);
if (b2)
{
cout << "转换成功" << endl;
}
else
{
cout << "转换失败" << endl;
}
B2 *b22 = new B2();
A2 *a22 = dynamic_cast<A2 *>(b22);
if (a22)
{
cout << "转换成功" << endl;
}
else
{
cout << "转换失败" << endl;
}
}
3.实现动态联编
//三.动态联编
class Animal
{
public:
virtual void eat() = 0;
};
class Cat : public Animal
{
public:
void eat()
{
cout << "cat eat fish" << endl;
}
void sleep()
{
cout << "cat like sleeping" << endl;
}
};
class Dog : public Animal
{
public:
void eat()
{
cout << "dog eat bones" << endl;
}
void wag()
{
cout << "dog is wagging tail" << endl;
}
};
void display(Animal *a)
{
a->eat();
if (typeid(*a) == typeid(Cat))
{
Cat *c = dynamic_cast<Cat *>(a);
if (c)
{
c->sleep();
}
else
{
cout << "convert false!" << endl;
}
}
if (typeid(*a) == typeid(Dog))
{
Dog *d = dynamic_cast<Dog *>(a);
if (d)
{
d->wag();
}
else
{
cout << "convert false!" << endl;
}
}
}
void test3()
{
Cat *c = new Cat();
display(c);
Dog *d = new Dog();
display(d);
}
int main()
{
test3();
return 0;
}