C++类型转换详解

 更新时间:2021年10月4日 20:01  点击:2149

C++对于内置类型有隐式或显式的类型转化,如int,double,long,char,但是,C++还有类这个概念,类是一种自定义类型,为了让类(自定义类型)达到内置类型的层次,C++对类也挺提供一些方法进行自动或者强制类型转换
C++的好多工作,在我看来就是让自定义类型能和内置类型一样简单使用、操作。

内置类型的转换

    int a = 8;
	double b = 4.4;
	long c = a;//隐式类型转换
	long d = (long)b;//显式类型转换

这都是我们熟悉的,是编译器已经帮我们处理好了的。

自定义类型转换

对于自定义类型,其类型转换,都是我们可以自己实现,自己控制的。

/*
* 对石块类的 声明定义
*/
class Stone
{
public:
	Stone(double weight);
	Stone(int stone_type, double volume);
private:
	int _stone_type;
	double _weight;
	double _volume;
};
Stone::Stone(double weight)
{
	_stone_type = 1;
	_weight = weight;
	_volume = 10.5;
}
Stone::Stone(int stone_type, double volume=10.5)
{
	_stone_type = stone_type;
	_weight = 5.8;
	_volume = volume;
}

我们提供了Stone(double) 这个构造函数的重载,可以直接将double类型进行构造出一个类。

	Stone s1 = 24.5;
	Stone s2(10.5);
	Stone s3(21, 20.5);

对于Stone s1 = 24.5;而言,重新是由构造函数Stone(double)来创建一个临时的Stone对象,并将24.5作为初始值,随后,采用逐成员复值的方法,将该临时对象的内容复制到s1对象中。也就是将一个double类型的对象转换为Stone类型的对象。

这一过程称为隐式转换,它是自动进行的,不需要显式迁至类型转换。

注意:只有接受一个参数的构造函数才能作为转换函数,

像Stone(int stone_type, double volume)有两个参数,因此不能用来转换类型,然而,如果它第二代参数是个缺省,提供了默认值,其便可以用来进行int对象的转换。
这个转换函数是将那些其他(内置或者其他的类型)类型向类类型转换

explicit 关键字

将构造函数用作于自动类型转换函数似乎是一项不错的特性,但是这种自动转换的并不是在所有情况下都需要,某些情况下,不需要这种转换,但是却意外的进行了转换。

所以C++提供了关键字explicit,用于关闭这种自动转换。

explicit的意思是:显式的,明确的。

可以加在函数声明前

explicit Stone(double weight) 

这样,只能显式调用这个构造。

在这里插入图片描述

Stone s1 = Stone(24.5);
Stone s4 = (Stone)19.99;//非常像内置类型的显式转换

这样显式调用就没什么问题。

提醒

还有一个要提醒的:如果像这个一样,

在这里插入图片描述

有两个参数的函数,

在这里插入图片描述

有一个加了explicit,另一个没加,如果还像刚才一样,隐式转换的那种,还是能泡过的,因为,会执行两个参数的构造函数,因为就这个是能匹配的,这肯会造成一个隐患,给大家提个醒,要加explicit,构成重载的函数最好都加上,不然出来Bug就不好找了。

提问:编译器在什么时候使用Stone(double)?

如果在声明中使用了关键字explicit,则Stone(double)将只能用于显式强制类型转换,
如果没有的话,就还能用于隐式类型转换

  • 将Stone对象初始化为double值时,例:Stone s1 = 24.5;
  • double值赋给Stone对象,例:Stone s5;s5 = 19.7;
  • 将double值传递给接受Stone参数的函数,例:

void Print(const Stone& tmp) 
{cout << "Print" << endl;}
Print(19.7);

  • 返回值被声明为Stone类型的函数试图返回double。
  • 在上述任意一种情况下,使用可转换为double类型的内置类型时(只要能转换成double类型的内置类型对象,都能这样隐式调用)

    Stone s5;
	s5 = 19;
	Stone s6(100);

同时,要记住编译器不能处理具有二义性的调用。

转换函数

概念介绍

上面也介绍过转换函数,

不过那是内置类型转换为类类型,
这里的是类类型转换为内置类型。

转换函数的形式:operator typeName();

1.转换函数必须是类方法

2.转换函数不能指定返回类型

3.转换函数不能有参数

例如:转换为double类型的函数原型:

operator double();

typeName(这里指 double ,因此就不需要指定返回类型。转换函数是类方法意味着:它需要类对象来调用,从而告知函数要转换的值。因此,函数不需要函数。

Stone::operator double() const
{
	return _weight;
}

Stone s4 = (Stone)19.99;
double d1 = s4;//隐式调用
double d2 = (double)s4;//显式
double d3 = double(s4);//显式

且这调用的都是转换函数。

自动引用类型转换

double d1 = s4;//隐式调用

都是自动转换。

还有赋值的情况,可能会存在内置类型之间的转换。

long l1 = s4;

这里可没有long的转换函数,说明是转化为double后,又转换为了long类型。

缺陷

转换函数都存在缺陷。

提供自动调用、隐式转换的函数存在的问题:使用者不希望转换时,转换函数也可能进行了转换。

所以最好还是要加上explicit,只有显式调用时,才能进行转换。

或者,使用一些功能相同的类方法来继续代替,这样,如果类成员又类型一样的也能转换。

double Stone::Stone_to_double_weight(void)
{
	return _weight;
}
double Stone::Stone_to_double_volume(void)
{
	return _volume;
}

我觉得这玩意比那个还好用一些。

总结

应谨慎使用隐式转换函数。通常,最好选择仅在被显式调用时才会执行的函数

C++为类提供了下面的类型转换

  • 只有一个参数的类构造函数用于将类型与该参数相同的值转换为类类型。
  • 被称为转换函数的特殊类成员运算符函数,用于将类对象转换为其他类型,转换函数是类成员,没有返回类型,没有参数,名为operator typeName();

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注猪先飞的更多内容!

[!--infotagslink--]

相关文章

  • php svn操作类

    以前我们开发大型项目时都会用到svn来同步,因为开发产品的人过多,所以我们会利用软件来管理,今天发有一居然可以利用php来管理svn哦,好了看看吧。 代码如下 ...2016-11-25
  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • PHP 数据库缓存Memcache操作类

    操作类就是把一些常用的一系列的数据库或相关操作写在一个类中,这样调用时我们只要调用类文件,如果要执行相关操作就直接调用类文件中的方法函数就可以实现了,下面整理了...2016-11-25
  • 使用PHP+JavaScript将HTML页面转换为图片的实例分享

    这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 在数据库里将毫秒转换成date格式的方法

    在开发过程中,我们经常会将日期时间的毫秒数存放到数据库,但是它对应的时间看起来就十分不方便,我们可以使用一些函数将毫秒转换成date格式。 一、 在MySQL中,有内置的函数from_unixtime()来做相应的转换,使用如下: 复制...2014-05-31
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • Javascript类型转换的规则实例解析

    这篇文章主要介绍了Javascript类型转换的规则实例解析,涉及到javascript类型转换相关知识,对本文感兴趣的朋友一起学习吧...2016-02-27
  • JS+CSS实现分类动态选择及移动功能效果代码

    本文实例讲述了JS+CSS实现分类动态选择及移动功能效果代码。分享给大家供大家参考,具体如下:这是一个类似选项卡功能的选择插件,与普通的TAb区别是加入了动画效果,多用于商品类网站,用作商品分类功能,不过其它网站也可以用,...2015-10-21
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • Php文件上传类class.upload.php用法示例

    本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
  • 美图秀秀把普通照片快速转换成卡通效果教程

    今天小编在这里就来给美图秀秀的这一款软件的使用者们来说下把普通照片快速转换成卡通效果的教程,各位想知道具体制作步骤的使用者们,那么下面就快阿里跟着小编一起看一...2016-09-14
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • PHP实现递归无限级分类

    在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性。那么PHP是如何实现无限级分类的呢?我们在本文中使用递归算法并结合mysql数据表实现无限级分类。 递归,简单的说就是一段程序代码的重复调用,当把...2015-10-23
  • 详解C++ bitset用法

    这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 浅谈C++中的string 类型占几个字节

    本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25