C++中四种类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast要点解析

1.static_cast

typename dst_ptr = static_cast<typename> (src_ptr)

可用于c++基本类型之间的转换,子类与派生类之间的指针转换,类不要求有虚函数。编译时检查转换有效性,不关联的类指针转换会在编译时报错。与dynamic_cast不同的是指向基类对象的指针也可以转换为派生类指针,而这种情况是不安全的,dynamic_cast在这种情况会返回NULL,因为派生类指针指向的并不是一个派生类对象。


2.dynamic_cast

typename dst_ptr = dynamic_cast<typename> (src_ptr)

基类必须有虚函数,否则编译出错。c++在运行时不关心指针是什么类型的,关心的是指针指向的对象是什么类型的,简单的一种情况是将基类对象赋值给派生类指针,那么在派生类指针访问派生类有而基类没有的方法时就会出现访问虚函数表崩溃,另外dynamic_cast还支持交叉转换,如下:

    class A
    {
    public:
        int m_iNum;
        virtual void f(){}
    };

    class B:public A
    {
        
    };

    class D:public A
    {
        
    };

    void foo()
    {    
        B *pb = new B;    
        pb->m_iNum = 100;    
        D *pd1 = static_cast<D *>(pb); //compile error    
        D *pd2 = dynamic_cast<D *>(pb); //pd2 is NULL    
        delete pb;    
    }


dynamic_cast是用的比较多的类型转换符,不过这个转换符在转换的时候有性能问题。


3.reinterpret_cast

typename dst_ptr = reinterpret_cast<typename> (src_ptr)

类似c的强制转换,不改变指针的值直接进行二进制的复制,不过不能移除const等修饰。

static_cast 和 reinterpret_cast 操作符修改了操作数类型,它们不是互逆的。

static_cast 在编译时使用类型信息执行转换,在转换执行必要的检测(诸如指针越界计算, 类型检查)。


4.const_cast

const typename dst_ptr = const_cast<const typename> (src_ptr)

typename dst_ptr = const_cast<typename> (src_ptr)

指针转换时移除指针的const属性或者添加非常量指针的const属性



5.示例代码

#include <stdlib.h>
#include <stdio.h>

class base
{
public:
	base() :m_base(1)
	{
		printf("base\n");
	}
	virtual void myself()
	{
		printf("m_base\n");
	}
private:
	int m_base;
};

class derive:public base
{
public:
	derive():m_derive(3),m_base(2)
	{
	}
	virtual void myself()
	{
		printf("m_derive\n");
	}
	virtual void print()
	{
		printf("print\n");
	}
private:
	int m_base;
	int m_derive;
};

class other
{
public:
	virtual void myself(){}
};

int main(int argc, char* argv[])
{
	int count = 0;
	double score = 0.0;

	count = static_cast<int>(score);

	base ptr_base = base();

	base* ptr_base1 = new base();
	base* ptr_base2 = new derive();

	derive* ptr_derive1 = new derive();
	derive* ptr_derive2 = static_cast<derive *>(new base());
	
	//ptr_derive2->print();

	other* ptr_other1 = new other();

	//ptr_base1 = static_cast<base *>(ptr_derive1);
	ptr_derive1 = static_cast<derive *>(ptr_base1);
	//ptr_other1 = static_cast<other *>(ptr_base1);

	ptr_base1 = dynamic_cast<base *>(ptr_derive1);
	ptr_derive1 = dynamic_cast<derive *>(ptr_base1);
	ptr_other1 = dynamic_cast<other *>(ptr_base1);

	const base* cptr_base = new base();
	cptr_base = ptr_base1;
	ptr_base1 = const_cast<base *>(cptr_base);
	cptr_base = const_cast<const base *>(ptr_base1);

	cptr_base = ptr_base1;

	//ptr_base1 = reinterpret_cast<base *>(cptr_base);
	ptr_base1 = reinterpret_cast<base *>(ptr_derive1);
	ptr_base1 = reinterpret_cast<base *>(ptr_other1);

	return 0;
}



6.参考资料

http://blog.chinaunix.net/uid-26548237-id-3954104.html

http://www.cnblogs.com/carsonzhu/p/5251012.html

http://poplars.blog.163.com/blog/static/1394221742013021111210567/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值