优秀的编程知识分享平台

网站首页 > 技术文章 正文

C++中的类型转换运算符(c++四种类型转换运算符)

nanyue 2024-08-10 18:36:13 技术文章 11 ℃

C++支持以下4种类型的转换运算符:

  • const_cast
  • static_cast
  • dynamic_cast
  • reinterpret_cast

1. const_cast

const_cast用于舍弃变量的常数。以下是有关const_cast的一些有趣的事实。

1)const_cast可用于更改const成员函数内的非const类成员。考虑以下代码片段。在const成员函数fun()中,编译器将“ this”视为“const student * const this”,即“ this”是指向常量对象的常量指针,因此编译器不允许通过以下方式更改数据成员 “this”指针。const_cast将“ this”指针的类型更改为“ student * const this”。

#include <iostream> 
using namespace std; 
  
class student 
{ 
private: 
    int roll; 
public: 
    // constructor 
    student(int r):roll(r) {} 
  
    // A const function that changes roll with the help of const_cast 
    void fun() const
    { 
        ( const_cast <student*> (this) )->roll = 5; 
    } 
  
    int getRoll()  { return roll; } 
}; 
  
int main(void) 
{ 
    student s(3); 
    cout << "Old roll number: " << s.getRoll() << endl; 
  
    s.fun(); 
  
    cout << "New roll number: " << s.getRoll() << endl; 
  
    return 0; 
} 

输出:

Old roll number: 3
New roll number: 5

2)const_cast可用于将const数据传递给不接收const的函数。例如,在下面的程序中,fun()接收普通指针,但是可以在const_cast的帮助下传递指向const的指针。

#include <iostream> 
using namespace std; 
  
int fun(int* ptr) 
{ 
    return (*ptr + 10); 
} 
  
int main(void) 
{ 
    const int val = 10; 
    const int *ptr = &val; 
    int *ptr1 = const_cast <int *>(ptr); 
    cout << fun(ptr1); 
    return 0; 
} 

输出:

20

3)修改最初声明为const的值是未定义的行为。考虑下面的程序。程序的输出未定义。变量“ val”是一个常量变量,调用“ fun(ptr1)”尝试使用const_cast修改“ val”。

#include <iostream> 
using namespace std; 
  
int fun(int* ptr) 
{ 
    *ptr = *ptr + 10; 
    return (*ptr); 
} 
  
int main(void) 
{ 
    const int val = 10; 
    const int *ptr = &val; 
    int *ptr1 = const_cast <int *>(ptr); 
    fun(ptr1); 
    cout << val; 
    return 0; 
} 

输出:

Undefined Behavior

修改最初未声明为const的值是可以的。例如,在上述程序中,如果我们从val声明中删除const,则该程序将产生20作为输出。

#include <iostream> 
using namespace std; 
  
int fun(int* ptr) 
{ 
    *ptr = *ptr + 10; 
    return (*ptr); 
} 
  
int main(void) 
{ 
    int val = 10; 
    const int *ptr = &val; 
    int *ptr1 = const_cast <int *>(ptr); 
    fun(ptr1); 
    cout << val; 
    return 0; 
} 

4)const_cast比简单类型转换更安全。从某种意义上讲,如果投射类型与原始对象不同,则不会发生投射,这是比较安全的。例如,以下程序编译失败,因为将“ int *”类型转换为“ char *” 。

#include <iostream> 
using namespace std; 
  
int main(void) 
{ 
    int a1 = 40; 
    const int* b1 = &a1; 
    char* c1 = const_cast <char *> (b1); // compiler error 
    *c1 = 'A'; 
    return 0; 
} 

输出:

prog.cpp: In function ‘int main()’:
prog.cpp:8: error: invalid const_cast from type 'const int*' to type 'char*'

5)const_cast也可以用来抛弃volatile属性。例如,在下面的程序中,b1的typeid是PVKi(指向易失性和恒定整数的指针),而c1的typeid是Pi(指向整数的指针)。

#include <iostream> 
#include <typeinfo> 
using namespace std; 
  
int main(void) 
{ 
    int a1 = 40; 
    const volatile int* b1 = &a1; 
    cout << "typeid of b1 " << typeid(b1).name() << '\n'; 
    int* c1 = const_cast <int *> (b1); 
    cout << "typeid of c1 " << typeid(c1).name() << '\n'; 
    return 0; 
} 

输出:

typeid of b1 PVKi
typeid of c1 Pi

2. Static Cast

这是可以使用的最简单的类型转换。它是一个编译时间转换,它可以进行类型之间的隐式转换(例如int到float或指向void *的指针),还可以调用显式转换函数(或隐式函数)。

示例:

#include <iostream> 
using namespace std; 
int main() 
{ 
    float f = 3.5; 
    int a = f; // this is how you do in C 
    int b = static_cast<int>(f); 
    cout << b; 
} 

输出:

3

3. reinterpret_cast

reinterpret_cast是C ++中使用的一种强制转换运算符。

  • 它用于转换任何类型的另一个指针的一个指针,无论该类是否相互关联。
  • 它不检查指针类型和指针所指向的数据是否相同。

语法:

data_type *var_name = 
       reinterpret_cast <data_type *>(pointer_variable);

示例:

// CPP program to demonstrate working of  
// reinterpret_cast 
#include <iostream> 
using namespace std; 
  
int main() 
{ 
    int* p = new int(65); 
    char* ch = reinterpret_cast<char*>(p); 
    cout << *p << endl; 
    cout << *ch << endl; 
    cout << p << endl; 
    cout << ch << endl; 
    return 0; 
} 

输出:

65
A
0x1609c20
A

使用reinterpret_cast的目的

1)reinterpret_cast是一种非常特殊且危险的类型转换操作符。建议使用正确的数据类型使用它,即(指针数据类型应与原始数据类型相同)。

2)它可以将任何指针类型转换为任何其他数据类型。

3)当我们要使用位时使用它。

4)如果我们使用这种类型的cast,那么它将成为一种不可移植的产品。因此,除非需要,建议不要使用这个概念。

5)它仅用于将任何指针转换为原始类型。

6)布尔值将转换为整数值,即0表示false,1表示true。

// CPP code to illustrate using structure 
#include <bits/stdc++.h> 
using namespace std; 
  
// creating structure mystruct 
struct mystruct { 
    int x; 
    int y; 
    char c; 
    bool b; 
}; 
  
int main() 
{ 
    mystruct s; 
  
    // Assigning values 
    s.x = 5; 
    s.y = 10; 
    s.c = 'a'; 
    s.b = true; 
  
    // data type must be same during casting 
    // as that of original 
  
    // converting the pointer of 's' to, 
    // pointer of int type in 'p'. 
    int* p = reinterpret_cast<int*>(&s); 
  
    cout << sizeof(s) << endl; 
  
    // printing the value currently pointed by *p 
    cout << *p << endl; 
  
    // incrementing the pointer by 1 
    p++; 
  
    // printing the next integer value 
    cout << *p << endl; 
  
    p++; 
  
    // we are casting back char * pointed 
    // by p using char *ch. 
    char* ch = reinterpret_cast<char*>(p); 
  
    // printing the character value 
    // pointed by (*ch) 
    cout << *ch << endl; 
  
    ch++; 
  
    /* since, (*ch) now points to boolean value, 
    so it is required to access the value using  
    same type conversion.so, we have used  
    data type of *n to be bool. */
  
    bool* n = reinterpret_cast<bool*>(ch); 
    cout << *n << endl; 
  
    // we can also use this line of code to 
    // print the value pointed by (*ch). 
    cout << *(reinterpret_cast<bool*>(ch)); 
  
    return 0; 
} 

输出:

12
5
10
a
1
1

程序2

// CPP code to illustrate the pointer reinterpret 
#include <iostream> 
using namespace std; 
  
class A { 
public: 
    void fun_a() 
    { 
        cout << " In class A\n"; 
    } 
}; 
  
class B { 
public: 
    void fun_b() 
    { 
        cout << " In class B\n"; 
    } 
}; 
  
int main() 
{ 
    // creating object of class B 
    B* x = new B(); 
  
    // converting the pointer to object 
    // referenced of class B to class A 
    A* new_a = reinterpret_cast<A*>(x); 
  
    // accessing the function of class A 
    new_a->fun_a(); 
    return 0; 
} 

输出:

In class A

Tags:

最近发表
标签列表