C++之7|转换函数

七、转换函数

1、标准转换函数

//1. reinterpret_cast<new type>(expression)
	将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型
//2. const_cast<new type>(expression)
	const 常量指针与普通指针间的相互转换
	注:不能将非常量指针变量转换为普通变量
//3. static_cast<new type>(exprssion)
	主要用于基本类型间的相互转换,和具有继承关系间的类型转换
//4. dynamic_cast<newtype>(expression)
	只有类中含有虚函数才能使用 dynamic_cast ,只能在继承类对象间转换
	/*dynamic_cast具有类型检查功能,比static_cast更安全*/
//1和2比较危险,后续可能会被淘汰,3和4在项目中偶尔还会遇到

例30、reinterpret_cast

首先回顾C语言的强制转换,错误案例如下

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{

	int a;

	char *p =&a;

}

错误结果如下

@ubuntu:/mnt/hgfs/ub2$ g++ cast1.cpp 
cast1.cpp: In function ‘int main()’:
cast1.cpp:11:12: error: cannot convert ‘int*’ to ‘char*’ in initialization
  char *p =&a;
            ^
@ubuntu:/mnt/hgfs/ub2$ 

所以需要进行强制转换

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{

	int a;

	char *p =(char *)&a;

}

以上是C语言的做法,在C++中,写成如下形式

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{

	int a;

	char *p =reinterpret_cast<char *>(&a);

}

例31、const_cast

同样的道理,在C语言中,对修饰为常量的参数取地址会出错,如下

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{

	const int b = 100;
    int *p = &b;

}
@ubuntu:/mnt/hgfs/ub2$ g++ cast3.cpp 
cast3.cpp: In function ‘int main()’:
cast3.cpp:10:14: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
     int *p = &b;
              ^~
@ubuntu:/mnt/hgfs/ub2$ 

在C++中,有方式实现把常量的地址强转为其它的数据类型

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{

	const int b = 100;
    int *p =const_cast<int *>(&b);

}

注意,这种做法很危险,不推荐。

例32、static_cast

然后接下来是静态方面的强制转换

#include <stdio.h>
#include <iostream>

using namespace std;

class A{

};

class B:public A{

};

int main()
{

		A a;	
		B &p = a;

}

运行结果报错

@ubuntu:/mnt/hgfs/ub2$ g++ cast5.cpp 
cast5.cpp: In function ‘int main()’:
cast5.cpp:19:10: error: invalid initialization of reference of type ‘B&’ from expression of type ‘A’
   B &p = a;
          ^
@ubuntu:/mnt/hgfs/ub2$ 

在C++中可以进行强制转换,写成

#include <stdio.h>
#include <iostream>
#include <typeinfo>

using namespace std;

class A{

};

class B:public A{

};

int main()
{

		A a;	
		B &p = static_cast<B &>(a);

}

这种做法跟const_cast 那样也是很危险,不推荐。

例33、dynamic_cast

这时候可以使用高级一点的强制转换dynamic_cast

#include <stdio.h>
#include <iostream>

using namespace std;

class A{

};

class B:public A{

};

int main()
{

		A a;	
		B &p = dynamic_cast<B &>( a );

}

这时候错误反馈信息就很到位

@ubuntu:/mnt/hgfs/ub2$ g++ cast7.cpp 
cast7.cpp: In function ‘int main()’:
cast7.cpp:18:31: error: cannot dynamic_cast ‘a’ (of type ‘class A’) to type ‘class B&(source type is not polymorphic)
   B &p = dynamic_cast<B &>( a );
                               ^
@ubuntu:/mnt/hgfs/ub2$ 

当使用到虚函数时候,就变成了警告,编译也让过,但执行就会出问题,如下所示

#include <stdio.h>
#include <iostream>
#include <typeinfo>

using namespace std;

class A{
public:
	virtual void show()
	{
		cout<<"aaaaaaa"<<endl;
	}
};

class B:public A{
public:
	void show()
	{
		cout<<"bbbbbbbbbbbbaaaaaaa"<<endl;
	}

};

int main()
{
		A a;	
		B &p = dynamic_cast<B &>( a );
}

结果

@ubuntu:/mnt/hgfs/ub2$ g++ cast8.cpp 
cast8.cpp: In function ‘int main()’:
cast8.cpp:27:31: warning: dynamic_cast of ‘A a’ to ‘class B&’ can never succeed
   B &p = dynamic_cast<B &>( a );
                               ^
@ubuntu:/mnt/hgfs/ub2$ ./a.out
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)
@ubuntu:/mnt/hgfs/ub2$ 

执行出现段错误是因为出现异常却没设法去捕获异常而造成的。这时候需要用到异常处理(之前所学内容例29),修改如下

#include <stdio.h>
#include <iostream>
#include <typeinfo>

using namespace std;

class A{
public:
	virtual void show()
	{
		cout<<"aaaaaaa"<<endl;
	}
};

class B:public A{
public:
	void show()
	{
		cout<<"bbbbbbbbbbbbaaaaaaa"<<endl;
	}

};

int main()
{
	try{

		A a;	
		B &p = dynamic_cast<B &>( a );
	}
	catch(bad_cast e)
	{
		cout<<e.what()<<endl;
	}
}

这时候编译虽然警告,但最后能够成功执行

@ubuntu:/mnt/hgfs/ub2$ g++ cast9.cpp 
cast9.cpp: In function ‘int main()’:
cast9.cpp:29:31: warning: dynamic_cast of ‘A a’ to ‘class B&’ can never succeed
   B &p = dynamic_cast<B &>( a );
                               ^
@ubuntu:/mnt/hgfs/ub2$ ./a.out
std::bad_cast
@ubuntu:/mnt/hgfs/ub2$ 

2、自定义转换函数

例34、operator

#include <stdio.h>
#include <unistd.h>
#include <iostream>

using namespace std;

class Timer{
public:
	Timer()
	{
		hour = 0;
		min = 0;
		sec = 0;
	}
	~Timer()
	{

	}

	void addtimer(int sec=1)
	{
		this->min += (this->sec+sec)/60;
		this->sec = (this->sec+sec)%60;
	}

	void show()
	{
		printf("%2d:%2d:%2d\n", hour, min, sec);
	}

	Timer operator+(int sec)
	{
		Timer tem;
		tem.sec = this->sec+sec;
		return tem;
	}
	Timer operator+(Timer &x)
	{
		Timer tem;
		tem.sec = sec+x.sec;
		tem.min = min+x.min;
		tem.hour = hour+x.hour;
		return tem;
	}

	Timer operator++(int)
	{
		Timer tem = *this;//backup
	
		sec++;

		return tem;
	}

	Timer operator++()
	{
		sec++;
		return *this;
	}

	bool operator==(Timer &x)
	{
		if(sec==x.sec && min==x.min && hour==x.hour)
			return true;
		return false;
	}

	int &operator[](int i)
	{
		switch(i)
		{
		case 0: 
			return hour;
		case 1: 
			return min;
		case 2: 
			return sec;
		}
	}
//转换成int就operator int()
	operator int()
	{
        //实现相应的功能,此处是转成秒
		return sec+min*60+hour*60*60;
	}

	friend ostream &operator<<(ostream &out, const Timer &t);
private:
	int hour;
	int min;
	int sec;
};

ostream &operator<<(ostream &out, const Timer &t)
{
	out << "hour: "<<t.hour << " min: "<<t.min<<" sec: "<<t.sec<< endl;
}

int main()
{
	Timer t;
	t.addtimer(3);

	int sec = t;	//强转为整形类型
	
	cout<< sec <<endl;
}

3、隐式构造

例35、explicit

#include <iostream>

using namespace std;

class mempool{
public:
	//构造函数
	//mempool(int size){
	//explicit隐式构造
	explicit mempool(int size){
		data = new char[size];	
		cout<< "cccccccccc" <<endl;
	}
	~mempool()
	{
		delete [] data;
	}

private:
	char *data;
};

int main()
{
	//调用构造函数
//	mempool a(100);
	//在平常构造函数时无法去识别下式子是赋值100还是表示a大小为100,使用explicit隐式构造可以报错区分
	mempool a = 100;
}

错误提示

@ubuntu:/mnt/hgfs/ub2$ g++ mempool.cpp 
mempool.cpp: In function ‘int main()’:
mempool.cpp:28:14: error: conversion from ‘int’ to non-scalar type ‘mempool’ requested
  mempool a = 100;
              ^~~
@ubuntu:/mnt/hgfs/ub2$ 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值