c++_note_8_类型转换

9. c++类型转换

c仅支持强制类型转换(cast),TYPE a = (TYPE)a;

c++支持4种风格的类型转换操作符:

  • static_cast,编译器认可;
  • reinterpret_cast,重新解释类型,相当于强制转换,编译器不认可;
  • dynamic_cast,如子类和父类之间的多态类型转换,不建议;
  • const_cast,即转换常量属性,不建议。

前两个合起来相当于c的强制类型转换。

格式举例:int a = static_cast<int>(b);

我们应尽量避免使用类型转换。

static_cast

实现基本数据类型之间的转换,如int转换为char,编译器会做类型检查。

int a = 3.14这样的c风格隐式转换会出现warning;int a = static_cast<int>(3.14)则不会。

凡是可以隐式转换的地方都可以用static_cast

但是,静态转换不支持不同类型指针之间的转换,如int*char *reinterpret_cast则支持。

reinterpret_cast

可以转化任何内置的数据类型为其他任何的数据类型,不到万不得已绝对不要用。

dynamic_cast

可以运行时进行类型检查,其他三种都是编译时完成的。

如果转换时非父子关系,则返回nullptr。

使用时,基类中一定要有虚函数。

#include<iostream>
using namespace std;

class Person
{
public:
	virtual void come() = 0;
};

class Worker : public Person
{
public:
	virtual void come()
	{
		cout<<"clock in."<<endl;
	}
	
	void work()
	{
		cout<<"work."<<endl;
	}
};

class Boss : public Person
{
public:
	virtual void come()
	{
		cout<<"check."<<endl;
	}
	void rest()
	{
		cout<<"rest."<<endl;
	}
};

void func(Person *p)
{
	p->come();
	
	Worker * pworker = dynamic_cast<Worker *>(p);
	if(pworker != NULL)
	{
		pworker->work();
	}
	
	Boss * pboss = dynamic_cast<Boss *>(p);
	if(pboss != NULL)
	{
		pboss->rest();
	} 
}

int main(int argc, char *argv[])
{
	Worker worker;
	Boss boss;
	func(&worker);
	func(&boss);
	
	cin.get();
	return 0;
}
/*
clock in.
work.
check.
rest.
*/

upcast时,dynamic_caststatic_cast的效果是一样的;

downcast时,dynamic_cast具有类型检查的功能,比static_cast更安全。转换成功则返回指向类的指针或引用,失败则返回NULL。

Person *pp = static_cast<Person*>(&boss);

不建议使用,除非是单元测试, 如果你需要在运行时确定类型信息, 说明有设计缺陷。

const_cast

它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

只读转换为可写时,要确保这块内存可写。

#include<iostream>
using namespace std;

void func(const char *s)
{
	char *p = const_cast<char*>(s);
	p[0] = 'A';
}

int main(int argc, char *argv[])
{
	char s[] = "abc";
    //char *s = "abc";
	func(s);
	printf("%s\n",s);
	cin.get();
	return 0;
}

对于int这种变量,需要对它的地址(指针)强转,间接修改变量值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值