C++类型转换目录
- 一.C语言的强制类型转换
- 二.static_cast
- 1.父类子类之间指针或引用的转换
- 2.基本数据类型的转换
- 3.空指针转换其他类型指针
- 4.其他类型指针转换为空指针
- 5.static_cast特点
- 6.完整代码
- 三.reinterpret_cast
- 1.数值与指针之间的转换
- 2.不同类型指针和引用之间的转换
- 3.reinterpret_cast特点
- 4.完整代码
- 四.dynamic_cast
- 1.基类指针转换为继承类指针
- 2.基类引用转换为继承类引用
- 3.dynamic_cast特点
- 4.完整代码
- 五.const_cast
- 1.去除const属性
- 2.const_cast特点
- 3.完整代码
- 六.类型转换怎么使用合适
- 1.static_cast
- 2.reinterpret_cast
- 3.dynamic_cast
- 4.const_cast
- 5.最后的忠告
- 6.c++大牛建议
一.C语言的强制类型转换
这个我不说,你们都知道了吧,就是(强制转换类型)类型
因为c++有新引入了类这些,所以我们来看看c++的类型转换.
二.static_cast
1.父类子类之间指针或引用的转换
完整代码在下面可以对比来学.
子类的指针可以转换为父类.
平时我们可能直接都是隐式转换,直接Animal*a1=dog1;
父类指针也可以转换为子类指针.
现在来看看引用,父与子之间也可以相互转换.
2.基本数据类型的转换
平时我们可能直接隐式转换 char c=n;
直接这样.
3.空指针转换其他类型指针
NULL就是空指针.
平时我们可能就写成的int*p=NULL;
4.其他类型指针转换为空指针
5.static_cast特点
- 比较’温柔’,隐式转换的差不多都可以用static_cast来进行转换
- 编译器会做一个检测,转换是否合理.
- 不支持不同类型的指针或引用转换
6.完整代码
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void cry() = 0;
};
class Dog :public Animal
{
public:
void cry()
{
cout << "汪汪汪" << endl;
}
};
class Cat :public Animal
{
public:
void cry()
{
cout << "喵喵喵" << endl;
}
};
int main()
{
Dog* dog1 = new Dog();
Animal* a1 =static_cast<Animal*> (dog1);//子类的指针转型到父类指针
a1 = dog1;//父类指针指向指向子类对象
Dog* dog = static_cast<Dog*>(a1);//父类的指针转型到子类指针
Cat* cat = static_cast<Cat*>(a1);
//dog = a1;//这样是不允许的,有一定的风险
Dog dog2;
Animal& a2 = static_cast<Animal&> (dog2);
Dog&dog3 = static_cast<Dog&>(a2);
int n = 100;
char c = static_cast<char>(n);
c = n;
int* p = static_cast<int*>(NULL);
p = NULL;
int* p1 = new int;
void* p2 = static_cast<void*>(p1);
p2 = p1;
return 0;
}
三.reinterpret_cast
1.数值与指针之间的转换
2.不同类型指针和引用之间的转换
父与子都可以进行指针和引用的转换.
而且还可以进行不同类型之间的转换.
3.reinterpret_cast特点
- static_cast是’温柔’的,那么reinterpret_cast则是强烈的.
- 可以数值与指针之间的转换.
- 可以不同指针类型之间的转换.
- 当然强制可能导致部分数据丢失.
4.完整代码
#include <iostream>
using namespace std;
class Animal
{
public:
void cry()
{
cout << "动物叫" << endl;
}
};
class Dog :public Animal
{
public:
void cry()
{
cout << "汪汪汪" << endl;
}
};
class Cat :public Animal
{
public:
void cry()
{
cout << "喵喵喵" << endl;
}
};
int main()
{
int* p = reinterpret_cast<int*> (0x88888);
int val = reinterpret_cast<int>(p);
Dog *dog1=NULL;
Animal* a1 = reinterpret_cast<Animal*>(dog1);
Animal* a3 = static_cast<Animal*>(dog1);//能用static_cast<>就用这个
Dog dog;
Animal* a2 = &dog;
a2->cry();
Dog* dog2 = reinterpret_cast<Dog*>(a2);
Dog* dog3 = static_cast<Dog*>(a2);//能用static_cast<>就用这个
Cat* cat = static_cast<Cat*>(dog2);
Cat* cat = reinterpret_cast<Cat*>(dog2);//不同类型也可以转换
Animal& a4 = dog;
Dog& dog4 = reinterpret_cast<Dog&>(a4);
dog2->cry();
cat->cry();
return 0;
}
四.dynamic_cast
1.基类指针转换为继承类指针
虚基类的话,那么我们就可以玩多态.
父类指针指向子类指针时,就可以发送多态.
但是当我们想要调用子类特有的函数时.
那么我们需要在函数中类型转换为子类.
这时我们就可以使用dynamic_cast
动态类型转换.
其会判断父类是不是指向要转换的目标类型,是的话,就返回这个子类指针,不是的话,会返回空.
2.基类引用转换为继承类引用
用引用的话,会判断父类是否是引用的要转换的类型,是的话,没有异常,不是的话会抛出bad_cast
异常.
3.dynamic_cast特点
- 在虚函数中有用
- 父类到子类的转换中,可判断父类的指向.
4.完整代码
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void cry() = 0;
};
class Dog :public Animal
{
public:
void cry()
{
cout << "汪汪汪" << endl;
}
void play()
{
cout << "汪汪队,汪汪队,打断你的狗腿!" << endl;
}
};
class Cat :public Animal
{
public:
void cry()
{
cout << "喵喵喵" << endl;
}
void play()
{
cout << "积极噶,积极噶,蹦蹦吧,蹦蹦吧!" << endl;
}
};
void play(Animal* animal)
{
animal->cry();
Dog* dog = dynamic_cast<Dog*>(animal);
if (dog)
{
dog->play();
}
else
{
cout << "你个猫!" << endl;
}
Cat* cat = dynamic_cast<Cat*>(animal);
if (cat)
{
cat->play();
}
else
{
cout << "你个狗!" << endl;
}
}
void play(Animal& animal)
{
animal.cry();
try
{
Dog& dog = dynamic_cast<Dog&>(animal);
dog.play();
}
catch (bad_cast bc)
{
cout << "你个猫!" << endl;
}
try
{
Cat& cat = dynamic_cast<Cat&>(animal);
cat.play();
}
catch (bad_cast bc)
{
cout << "你个狗!" << endl;
}
}
int main()
{
Dog* dog=new Dog;
Cat* cat = new Cat;
play(dog);
play(cat);
Dog dog1;
Cat cat1;
play(dog1);
play(cat1);
return 0;
}
五.const_cast
1.去除const属性
const的形参本是不能进行修改的,但是可以用const_cast
进行去除.
但是只能对指针和引用有用.
在常量区的字符串也不能进行去除.
因为指针所指向的内存不能进行修改.
2.const_cast特点
- 对指针和引用有用
3.完整代码
#include <iostream>
using namespace std;
void demo(const char* p)
{
char* p1 = const_cast<char*>(p);
p1[0] = 'A';
}
void demo(const int a)
{
int a1 = const_cast<int>(a);
}
int main()
{
char str[] = "1234567890";
demo(str);
cout << str << endl;
const char* cp= "987654321";//不可以会异常
demo(cp);
return 0;
}
六.类型转换怎么使用合适
1.static_cast
- 隐式转换
- 基本类型转换
- 父子类之间的合理转换
2.reinterpret_cast
- 不同类型之间,进行强制类型转换
- static_cast不能转换的用这个
- 但是这个很容易导致数据丢失
3.dynamic_cast
- 虚基类和子类之间的转换
4.const_cast
- 去除指针和引用变量的只读属性
5.最后的忠告
当你进行转换时,要知道转换前是什么类型,转换后是什么类型,转换后的结果是什么.
6.c++大牛建议
避免进行类型转换