c++类型转换运算符详解

c++提供了4个类型转换运算符,使得转换过程更加的规范。

目录

1、static_cast

2、const_cast

3、dynamic_cast  

4、reinterpret_cast


1、static_cast

语法:static_cast <type-name>( expression )

static_cast用于类型转换,但运行时没有类型检查来保证转换的安全性。主要有以下几种用途

1)用于基本数据类型之间的转换

​double a = 10.06;
int b = static_cast<int>(a);

cout << "a=" << a << endl;    //输出10.06
cout << "b=" << b << endl;    //输出10

2) 用于父类指针或引用转换为子类指针或引用(向下转换),或者把子类指针或引用转换为父类指针或引用(向上转换)

需要注意的是,进行向上转换是安全的。进行向下转换是不安全的。因为没有动态类型检查。

3)用于把指向void的指针转换为指向任何类型的指针

int value = 99;
void *a = &value;
char *b = static_cast<char*>(a);	

cout << "b=" << *b << endl;	//输出c

2、const_cast

语法:const_cast< type-name > (expression)

const_cast的用途是,用于执行只有一种用途的类型转换,即改变值为const类型或者volatile类型。使用它可以返回一个指向非常量的指针(或引用)。

栗子:

class Test
{
public:
	Test() :m_cnt(0)
	{}
	int m_cnt;
};

int main()
{
	const Test t;
	//t.m_cnt = 10;	//错误,不可修改
	cout << t.m_cnt << endl;	//输出0
	Test *n = const_cast<Test*>(&t);
	n->m_cnt = 10;
	cout << t.m_cnt << endl;	//输出10
    
    getchar();
    return 0;
}

再看下面一个栗子:

const int value = 10;
//int *p_value = &value;		//错误,const int*类型,不能用于初始化int*类型的实体
volatile const int *p_value = &value;  //正确

//*p_value = 30;	//错误,不能通过指针a来修改value的值
//但是我们就是想通过指针修改value的值呢,这时候const_cast登场了,
int* b = const_cast<int*>(p_value);
*b = 20;

cout << "*b=" << *b << endl;	    //输出20
cout << "value=" << value << endl;	//输出10
​

这里需要注意一个问题,通过const_cast转换后,已经可以通过指针b修改value的值了,对b取值的确是20,但是value却输出了10,难道是因为没有对value的值修改成功么?其实原因是c++编译器的机制,编译器对const变量进行了优化,把value放在了符号表中,为了取值操作更高效。当我们用指针b去改变value的值后,value所对应的内存地址存储的值已经变成20。但是符号表中的值却并没有改变。所有value还是输出10。而真实的value其实是20。

如果把const int value=10修改为volatile const int value = 10; 这时候再输出,发现value输出的是20。因为volatile修饰的变量,每次都是从寄存器中去读取的。

3、dynamic_cast  

语法:dynamic_cast< type-name > (expression)

dynamic_cast可用于向上转换,即将子类指针转换为父类指针,主要用于确保可以安全的调用虚函数,当然也可用于向下转换。

同dynamic_cast转换能够进行的前提条件就是父类中有虚函数,这个前提条件的原因主要是因为只有让父类指针或引用指向子类对象的情况下,转换才有意义。static_cast没有这个要求。

但是在类间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

栗子

class A
{
public:
	A() :m_cnt(0)
	{}
	int m_cnt;

	virtual void func(){}
};

class B :public A
{
public:
	char *p;
};

int main()
{
	//向上转换
	B b;
	A* a = dynamic_cast<A*>(&b);
	if (a == NULL){
		cout << "a = NULL" << endl;
	}else{
		cout << "a != NULL" << endl;
	}

	//向下转换
	A t;
	B* b1 = static_cast<B*>(&t);
	if (b1 == NULL){
		cout << "b1 = NULL" << endl;
	}
	else{
		cout << "b1 != NULL" << endl;
	}

	B* b2 = dynamic_cast<B*>(&t);
	if (b2 == NULL){
		cout << "b2 = NULL" << endl;
	}else{
		cout << "b2 != NULL" << endl;
	}

    return 0;
}

输出

可以看到,向下转换时,static_cast返回了B类型的指针,对它进行 B 类型的操作将是不安全。但是dynamic_cast返回为空。

4、reinterpret_cast

语法:reinterpret_cast <type-name>( expression )

它是C++中的强制类型转换符。这个转换我目前很少用到,先待定。

发布了133 篇原创文章 · 获赞 175 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/c_shell_python/article/details/104729399
今日推荐