C++四种强制类型转换运算符总结

2022-11-30 11:13:17 2150人已围观 37已点赞 18人已收藏

简介本文介绍C++中四种功能不同的强制类型转换运算符以进行强制类型转换:static_cast、reinterpret_cast、const_cast 和dynamic_cast。

C++强制类型 运算符

C++ 引入了四种功能不同的强制类型转换运算符以进行强制类型转换:static_cast、reinterpret_cast、const_cast 和 dynamic_cast。强制类型转换是有一定风险的,有的转换并不一定安全,如把整型数值转换成指针,把基类指针转换成派生类指针,把一种函数指针转换成另一种函数指针,把常量指针转换成非常量指针等。

C++ 强制类型转换运算符语法:

强制类型转换运算符 <要转换到的类型> (待转换的表达式)

static_cast

static_cast用于基本数据类型之间的转换,如把int转换成char,把int转换成float等等。C++的任何的隐式转换都是使用 static_cast来实现。

用法总结:

1.不能用于不同类型的指针之间互相转换
2.不能用于整型和指针之间的互相转换
3.不能用于不同类型的引用之间的转换

示例代码:

#include <iostream>
using namespace std;
int main()
{
	float f = 4.5;
    int n;
	char c = 'a';
    char* p = "C++实战网(www.cppszw.com)";
	int* p2 = NULL;
    n = static_cast<int>(f);  	 // n的值变为4
    n = static_cast<int>(p);     // 编译错误,static_cast不能将指针转换成整型
    p = static_cast<char*>(n);   // 编译错误,static_cast不能将整型转换成指针
	p2 = static_cast<int*>(&c);	 // 编译错误,static_cast不能将字符转换成指针
    return 0;
}

reinterpret_cast

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

用法总结:

1.用于进行各种不同类型的指针之间的互相转换
2.用于不同类型的引用之间的互相转换
3.用于指针和能容纳指针的整数类型之间的转换

示例代码1:

int* p = new int(65);
char* ch = reinterpret_cast<char*>(p);
cout << *p << endl;
cout << *ch << endl;
cout << p << endl;
cout << ch << endl;

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast

示例代码2:

class A
{
public:
	int i;
	int j;
	A(int n) :i(n), j(n) { }
};
void test_reinterpret_cast2()
{
	A a(100);
	int &r = reinterpret_cast<int&>(a); //	强行让 r 引用 a
	r = 200;  // 把 a.i 变成了 200
	cout << a.i << "," << a.j << endl;  // 输出 200,100
	int n = 300;
	A *pa = reinterpret_cast<A*> (&n); // 强行让 pa 指向 n
	pa->i = 400;  // n变成400
	pa->j = 500;  // 此条语句不安全,很可能导致程序崩溃
	cout << n << endl;  // 输出 400
	long long la = 0x12345678abcdLL;
	pa = reinterpret_cast<A*>(la); // la太长,只取低32位0x5678abcd拷贝给pa
	unsigned int u = reinterpret_cast<unsigned int>(pa);// pa逐个比特拷贝到u
	cout << hex << u << endl;  // 输出 5678abcd
	typedef void(*PF1) (int);
	typedef int(*PF2) (int, char *);
	PF1 pf1;  PF2 pf2;
	pf2 = reinterpret_cast<PF2>(pf1); // 两个不同类型的函数指针之间可以互相转换

}

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast

第 17 行的代码不安全,因为在编译器看来,pa->j 的存放位置就是 n 后面的 4 个字节。 本条语句会向这 4 个字节中写入 500。但这 4 个字节不知道是用来存放什么的,贸然向其中写入可能会导致程序错误甚至崩溃。

示例代码3:

// 结构体mystruct
struct mystruct {
	int x;
	int y;
	char c;
	bool b;
};
void test_reinterpret_cast3()
{
	mystruct s;
	s.x = 5;
	s.y = 10;
	s.c = 'a';
	s.b = true;

	// 在强制转换期间,数据类型必须与原始数据类型相同

	// 将's'指针转换为'p'中int类型的指针。
	int* p = reinterpret_cast<int*>(&s);
	cout << sizeof(s) << endl;

	// 打印当前由*p指向的值
	cout << *p << endl;
	// 将指针增加1
	p++;
	// 打印下一个整数值
	cout << *p << endl;
	p++;
	// 用char *ch将char *指向p。
	char* ch = reinterpret_cast<char*>(p);

	// 打印(*ch)指定的字符值
	cout << *ch << endl;
	ch++;
	bool* n = reinterpret_cast<bool*>(ch);
	cout << *n << endl;
	cout << *(reinterpret_cast<bool*>(ch)) << endl;
}

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast

示例代码4:

#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(int argc, char const *argv[])
{
    // 创建B类的对象
    B* x = new B(); 
    // 将指向B类引用的对象的指针转换为A类
    A* new_a = reinterpret_cast<A*>(x); 
    // 访问A类的函数。
    new_a->fun_a(); 
    return 0; 
}

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast


const_cast

const_cast 运算符仅用于进行去除 const 属性的转换,它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。

示例代码:

// const_cast
void test_const_cast()
{
	const string s = "C++实战网(www.cppszw.com)";
	// s = "Hello World!"; // 编译出错:const修饰符不支持修改
	string& p = const_cast<string&>(s);
	p = "Hello World!";
	cout << p.c_str() << endl; // 输出:Hello World!
}

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast


dynamic _cast

用 reinterpret_cast 可以将多态基类(包含虚函数的基类)的指针强制转换为派生类的指针,但是这种转换不检查安全性,即不检查转换后的指针是否确实指向一个派生类对象。dynamic_cast专门用于将多态基类的指针或引用强制转换为派生类的指针或引用,而且能够检查转换的安全性。对于不安全的指针转换,转换结果返回 NULL 指针。

dynamic_cast 是通过“运行时类型检查”来保证安全性的。dynamic_cast 不能用于将非多态基类的指针或引用强制转换为派生类的指针或引用——这种转换没法保证安全性,只好用 reinterpret_cast 来完成。

示例代码:

// dynamic_cast
class Base
{
public:
	virtual ~Base() {}
};
class Derived : public Base { };
void test_dynamic_cast()
{
	Base b;
	Derived d;
	Derived* pd;
	pd = reinterpret_cast <Derived*> (&b);
	if (pd == NULL)
		// 此处pd不会为 NULL。reinterpret_cast不检查安全性,总是进行转换
		cout << "unsafe reinterpret_cast" << endl; // 不会执行
	pd = dynamic_cast <Derived*> (&b);
	if (pd == NULL)  // 结果会是NULL,因为 &b 不指向派生类对象,此转换不安全
		cout << "unsafe dynamic_cast1" << endl;  // 会执行
	pd = dynamic_cast <Derived*> (&d);  // 安全的转换
	if (pd == NULL)  // 此处 pd 不会为 NULL
		cout << "unsafe dynamic_cast2" << endl;  // 不会执行
}

编译输出:

C++强制类型转换,static_cast,reinterpret_cast,const_cast,dynamic_cast

参考:

源码下载
  • 最近更新:   2022-06-15开发环境:   Visual Studio 2015
  • 源码大小:   15.11KB下载次数:  24 

更多为你推荐