栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++之7|转换函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++之7|转换函数

C++学习
  • 七、转换函数
    • 1、标准转换函数
      • 例30、reinterpret_cast
      • 例31、const_cast
      • 例32、static_cast
      • 例33、dynamic_cast
    • 2、自定义转换函数
      • 例34、operator
    • 3、隐式构造
      • 例35、explicit

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

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

#include 
#include 

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 
#include 

using namespace std;

int main()
{

	int a;

	char *p =(char *)&a;

}

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

#include 
#include 

using namespace std;

int main()
{

	int a;

	char *p =reinterpret_cast(&a);

}
例31、const_cast

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

#include 
#include 

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 
#include 

using namespace std;

int main()
{

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

}

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

例32、static_cast

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

#include 
#include 

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 
#include 
#include 

using namespace std;

class A{

};

class B:public A{

};

int main()
{

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

}

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

例33、dynamic_cast

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

#include 
#include 

using namespace std;

class A{

};

class B:public A{

};

int main()
{

		A a;	
		B &p = dynamic_cast( 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( a );
                               ^
@ubuntu:/mnt/hgfs/ub2$ 

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

#include 
#include 
#include 

using namespace std;

class A{
public:
	virtual void show()
	{
		cout<<"aaaaaaa"<
public:
	void show()
	{
		cout<<"bbbbbbbbbbbbaaaaaaa"<
		A a;	
		B &p = dynamic_cast( 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( 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 
#include 
#include 

using namespace std;

class A{
public:
	virtual void show()
	{
		cout<<"aaaaaaa"<
public:
	void show()
	{
		cout<<"bbbbbbbbbbbbaaaaaaa"<
	try{

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

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

@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( a );
                               ^
@ubuntu:/mnt/hgfs/ub2$ ./a.out
std::bad_cast
@ubuntu:/mnt/hgfs/ub2$ 

2、自定义转换函数 例34、operator
#include 
#include 
#include 

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:%2dn", 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: "<
	Timer t;
	t.addtimer(3);

	int sec = t;	//强转为整形类型
	
	cout<< sec < 
3、隐式构造 
例35、explicit 
#include 

using namespace std;

class mempool{
public:
	//构造函数
	//mempool(int size){
	//explicit隐式构造
	explicit mempool(int size){
		data = new char[size];	
		cout<< "cccccccccc" <
		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$ 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号