Cpp-类型转换

Cpp-类型转换

static_cast: 安全转换,可用于子类向基类的显示转换,是编译期转换,没有运行时类型检查

dynamic_cast: 基类向派生类的安全转换,只能对指针或引用进行转换,是运行时转换

reinterpret_cast: 一些危险转换,只是将二进制的值拷贝过去,没有考虑类型之间的关系

const_cast: 去掉const

举例:

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
// ptrTableA(8byte) | a(4byte) | NONE(4byte)
class A
{
public:
int a;
virtual void PrintA(){cout << "A\n";}
};

// ptrTableB(8bype) | b(4byte) | NONE(4byte)
class B
{
public:
int b;
virtual void PrintB(){cout << "B\n";}
};

// ptrTableAC(8byte) | a(4byte) | NONE(4byte) | ptrTableBC(8bype) | b(4byte) | NONE(4byte)
class C:public A, public B
{
public:
virtual void PrintA(){cout << "AC\n";}
virtual void PrintB(){cout << "BC\n";}
};

int main()
{
C c;
// 前两个值相同,后一个会偏移16
printf("%p %p %p\n", &c, reinterpret_cast<B*>(&c), static_cast<B*>(&c));

C* pc = new C;
pc->a = 1;
pc->b = 2;
cout << reinterpret_cast<A*>(pc)->a << endl; // 1, offset=4
cout << reinterpret_cast<B*>(pc)->b << endl; // 1, offset=4
reinterpret_cast<A*>(pc)->PrintA(); // AC, use ptrTableAC
reinterpret_cast<B*>(pc)->PrintB(); // AC, use ptrTableAC

cout << dynamic_cast<A*>(pc)->a << endl; // 1, offset=4
cout << dynamic_cast<B*>(pc)->b << endl; // 2, offset=16
dynamic_cast<A*>(pc)->PrintA(); // AC, use ptrTableAC
dynamic_cast<B*>(pc)->PrintB(); // BC, use ptrTableBC

cout << static_cast<A*>(pc)->a << endl; // 1, offset=4
cout << static_cast<B*>(pc)->b << endl; // 2, offset=16
static_cast<A*>(pc)->PrintA(); // AC, use ptrTableAC
static_cast<B*>(pc)->PrintB(); // BC, use ptrTableBC

A* pa = new A;
pa->a = 3;
cout << reinterpret_cast<C*>(pa)->a << endl; // 3, offset=4
cout << reinterpret_cast<C*>(pa)->b << endl; // ?, offset=16
reinterpret_cast<C*>(pa)->PrintA(); // A, use ptrTableA
reinterpret_cast<C*>(pa)->PrintB(); // invalid access

cout << dynamic_cast<C*>(pa)->a << endl; // error
cout << dynamic_cast<C*>(pa)->b << endl; // error
dynamic_cast<C*>(pa)->PrintA(); // error
dynamic_cast<C*>(pa)->PrintB(); // error

cout << static_cast<C*>(pa)->a << endl; // 3, offset=4
cout << static_cast<C*>(pa)->b << endl; // ?, offset=16
static_cast<C*>(pa)->PrintA(); // A, use ptrTableA
static_cast<C*>(pa)->PrintB(); // invalid access
}

Cpp-类型转换
http://example.com/2023/01/10/Cpp-类型转换/
作者
Chen Shuwen
发布于
2023年1月10日
许可协议