分别是: static_cast、dynamic_cast、reinterpret_cast、const_cast, 这4个被C++内置为关键字。

在C++标准库中,还扩展几大转换:

static_pointer_cast、dynamic_pointer_cast、reinterpret_cast、const_pointer_cast用于引用计数指针的转换,可以了解一下。

渊源

首先我们来说说,这几种转换的来源,或者为什么为这几个转换,当然这是C++扩展C时,必须要有几大转换。

在C语言中,只有一种强转,如下:

1
2
3
4
5
6
7
double b = 1.2;
int a = b;// <==> int a = (int) b;
// 又或者一些指针的转换:
char* t = (char*)malloc(4); 

由于C是弱类型语言,类型都是平凡类型(POD类型),所以转换,就仅仅只是一个类型上的转换。而C升级到C++的时候

增加了很多的特性,类、const关键字等等东西,在C中的指针或者结构体的转换,都是不改变内容的情况进行类型转换,

亦或者截断内容转换,像指针的转换,转换之后,除了类型,指向的地址是不会更改。

而C++中增加了类的概念,在对类对象或者指针进行强转时,C中强转就不够用了,比如:

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
// 例1:
class A
{
public:
    A()
    {
        qDebug() << (void*)this;
    }
};
class B
{
public:
    B()
    {
        qDebug() << (void*)this;
    }
};
class C : public A, public B
{
public:
    C()
    {
        qDebug() << (void*)this;
    }
};
C* c = new C;
B* b = c; //b的指针地址比C的指针地址要大1, 这是指针偏移的概念。
// 如果有虚函数,指针偏移则会更大。
// 例如2:
class A
{
public:
    virtual void func()
    {
    }
};
class B : public A
{
public:
    virtual void func()
    {
    }
};
B b;
A a = b; //此时a中的虚函数表的地址,是类a的虚函数表地址,b的则是b的,
// 也就是说,在强转的过程中,内容发生变化。

因此在C++中类的强转,发生了一些微妙上的变化,于是就有static_cast和reinterpret_cast,而原本C中强制类型转换,在

C++中我们仍然习惯称为强转,它实际上默认是静态类型转换,也就是C++的以下的转换是等价的:

1
2
3
4
5
6
7
8
9
double b = 3.1;
int a = b;  // <==> a = static_cast<int>(b);
C* c = new C;
B* b = c;  // <==>  B* b = static_cast<B*>(c);

显然这种强转和C的强转不是一码事,至少在C中指针转换,指针指向的内容是不会变的,而在C++中为了保证安全,强转

它可能会导致内容发生改变, 于是C++为了保留原有强转的概念,增加reinterpret_cast这个关键字,它称为C++的强制类型

转换。

总结一下:  C++在扩展C的过程中,虽然保留了C的强制转换的写法,但是为了安全,与C的强转有区别,因此C中的强转就是

静态类型转换,并增加reinterpret_cast保留类C强转的功能。

至于dynamic_cast, 在虚函数多态那一篇详细做了说明,但这里仍需要说明一点,为啥dynamic_cast和static_cast一个为静态、

一个为动态。(reinterpret_castC++的强制类型转换,因为不安全,所以并不常用)。

在C中用的更多的是static_cast和dynamic_cast, 同它们的名字一样,静态转换,是在编译期就已经决定好如何进行转换(如何指针偏移,

如何进行内容修改),运行按照规则转换就好,而动态类型转换,纯粹发生在运行期,靠的虚函数表,简单的说,静态类型转换不需要

依赖运行时的内容,而动态类型,则是需要依赖运行时的内容的。

最后就是const_cast, 这玩意纯粹是因为C++增加了const关键字,这个关键字就是欺骗编译期的东西,为的是增加代码的安全性、规范性和可读性。

尽量不要用,功能也非常简单,去除变量const修饰。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。