C++基础知识之"类型转换"

fengjingtu

类型转换名称和语法

C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:TYPE b = (TYPE) a;

C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。

static_cast:静态类型转换。如int转换成char

reinterpreter_cast:重新解释类型

dynamic_cast:命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

const_cast:字面上理解就是去const属性。

TYPE b =static_cast a;

类型转换一般性

1)static_cast<>() 静态类型转换,编译的时c++编译器会做类型检查;基本类型能转换 但是不能转换指针类型

2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释

3)一般性结论:

C语言中 能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型 解释。

总结:

static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖

reinterpret_cast<>()很难保证移植性。

dynamic_cast<>(),动态类型转换,安全的基类和子类之间转换;运行时类型检查

const_cast<>(),去除变量的只读属性**

典型用法

static_cast和reinterpret_cast
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void main()
{
double dPi = 3.1415926;

//静态的类型转换:在编译的时进行基本类型的转换能替代c风格的类型转换可以进行一部分检查
int num1 = static_cast<int> (dPi); //c++的新式的类型转换运算符
int num2 = (int)dPi; //c语言的旧式类型转换
int num3 = dPi; //隐士类型转换
cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;

char *p1 = "hello Rita " ;
int *p2 = NULL;
p2 = (int *)p1;

//基本类型能转换 但是不能转换指针类型
//p2 = static_cast<int *> (p1); //“static_cast”: 无法从“char *”转换为“int *”

//可以使用reinterpret_cast进行重新解释
p2 = reinterpret_cast<int *> (p1);
cout << "p1 " << p1 << endl;
cout << "p2 " << p2 << endl;

//一般性的结论:c语言中能隐式类型转换的在c++中可以用 static_cast<>()进行类型转换
//C++编译器在编译检查一般都能通过
//c语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型解释
system("pause");
return ;
}
const_cast用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

//典型用法 把形参的只读属性去掉
void Opbuf(const char *p)
{
cout << p << endl;
char *p2 = const_cast<char*>(p);
p2[0] = 'b';
cout << p << endl;
}

void main()
{
const char *p1 = "11111111111";

char *p2 = "22222222";

char *p3 = const_cast<char *>(p1);
char buf[100] = "aaaaaaaaaaaa";

Opbuf(buf);

//要保证指针所执行的内存空间能修改才行 若不能修改 还是会引起程序异常
//Opbuf("dddddddddddsssssssssssssss");
system("pause");
}
注意

程序员要清除的知道: 要转的变量,类型转换前是什么类型,类型转换后是什么类型。转换后有什么后果。

一般情况下,不建议进行类型转换;避免进行类型转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <iostream>

using namespace std;

//C++中的类型转换
//方式 TYPE b = (TYPE)a
//C语言中有隐式转换和强制转换
//C++风格中有四种转换类型
//static_cast:静态转换C中能够进行隐式转换的类型之间,可以使用静态转换,基本类型可以,指针不可以。发生在编译时候。
//reinterpreter_cast:重新解释类型转换,相当于C语言中的强制转换。
//dynamic_cast:动态类型转换,如父类和子类之间的多态类型转换,发生在运行时候
//const_cast:去除变量的const属性。

void static_reinterpret_cast_test()
{
int a = 97;
char b1 = static_cast<char>(a);//c++静态
char b2 = (char)a;//c风格
cout << "b1="<<b1<<" b2="<<b2 << endl;

char * name = "wulei";
int * pname1 = (int *)name;
//int * pname2 = static_cast<int *>(name);//类型转换无法实现
int * pname2 = reinterpret_cast<int *>(name);//同C类型的强制转换
cout << "name=" << name << ",pname1=" << pname1 << ",pname2=" << pname2 << endl;

}

class Animal
{
public:
virtual void cry() = 0;
};
class Dog :public Animal
{
public:
virtual void cry()
{
cout << "wang wang" << endl;
}
void doswim()
{
cout << "swim" << endl;
}
};
class Cat :public Animal
{
public:
virtual void cry()
{
cout << "miao miao" << endl;
}
void dosleep()
{
cout << "sleep all day" << endl;
}
};
class Book
{
void printBook()
{
cout << "book" << endl;
}
};


void objplay(Animal *animal)//会发生多态
{
animal->cry();
//如果是不同的子类,可以执行子类自己特有的函数
Dog *pdog = dynamic_cast<Dog *>(animal);
//如果animal是Dog类型的指针,那么pdog就不会为NULL,否则会
if (pdog!=NULL)
{
pdog->cry();
pdog->doswim();
}
Cat *pcat = dynamic_cast<Cat *>(animal);//同上
if (pcat!=NULL)
{
pcat->cry();
pcat->dosleep();
}

}
void dynamic_cast_test()
{
Animal *animal = NULL;
//可以使用静态类型转换将父类转换成子类。
Dog *pdog = static_cast<Dog *>(animal);
Cat *pcat = static_cast<Cat *>(animal);
//不可以将一个类静态转换成其他不相关类,可以使用强制类型转换。
Book *pbook = reinterpret_cast<Book *>(animal);

objplay(new Cat);
objplay(new Dog);

}
void const_cast_test(const char *p)//典型用法,把形参的只读属性去掉
{
cout << "p=" << p << endl;
char *p2 = const_cast<char *>(p);
p2[0] = 'b';
cout << "p=" << p << " ,p2=" << p2;
}
void main_cast()
{
static_reinterpret_cast_test();
dynamic_cast_test();
char p[10] = "hello";//修改的时候要确保至变量确实可以修改
const_cast_test(p);
system("pause");
return;
}