C++类型转换详解

目录
  • 内置类型的转换
  • 自定义类型转换
    • explicit 关键字
      • 提醒
    • 提问:编译器在什么时候使用Stone(double)?
  • 转换函数
    • 概念介绍
    • 自动引用类型转换
      • 缺陷
  • 总结

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();

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

(0)

相关推荐

  • C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

    目录 1. c强制转换与c++强制转换 2. static_cast.dynamic_cast.const_cast.reinterpret_cast dynamic_cast const_cast reinterpret_cast 3. c++强制转换注意事项 1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 c++除了能使用c语言的强制类型转

  • 一文搞懂C++中的四种强制类型转换

    在了解c++的强制类形转换的时候,先看看在c语言中是怎么进行强制类形转换的. C语言中的强制类形转换分为两种 隐式类型转换 显示类型转换 int main() { int a = 97; char ch = a; // 隐式类型转换 int b = (int)ch; // 显示类型转换 cout << "a = " << a << endl; cout << "ch = " << ch << e

  • C++类型转换的深入总结

    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a. C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. const_cast,字面上理解就是去const属性. static_cast,命名上理解是静态类型转换.如int转换成char. dynamic_cast,命名上理解是动态类型转换.如子类和父类之间的多态类型转换. reinterpret_cast,仅仅重新解释类型,但没有进行二进制的转换. 4种类型转换的格式,如

  • 浅谈C++为什么非要引入那几种类型转换

    众所周知C++关于类型转换引入了四种方式: static_cast const_cast dynamic_cast reinterpret_cast 为什么要引入这几种类型转换,它与C语言中的强制类型转换有什么区别? 这四种类型转换分别应用在什么场景? C++为什么要引入这几种强制类型转换? 我们都知道C++完全兼容C语言,C语言的转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了

  • C++类结构体与json相互转换

    目录 1. 背景与需求 2. 最终使用的样例代码 3. 实现方法 3.1 基础类型的转换 3.2 类成员注册 3.3 自定义类的转换 3.4 外部调用接口 1. 背景与需求 之前写C#的时候,解析json字符串一般使用的是开源的类库Newtonsoft.Json,方法十分简洁,比如: class Project { public string Input { get; set; } public string Output { get; set; } } JavaScriptSerializer

  • C/C++中数据类型转换详解及其作用介绍

    目录 概述 不同类型数据间的转换 隐式类型转换 强制类型转换 自己声明的类型转换 转换构造函数 类型转换函数 案例 应用 概述 在日常的开发中, 我们经常会用到数据类型转换, 所以我们要对数据类型转换有一定的了解. 不同类型数据间的转换 在 C++ 中, 某些标准类型的数据之间可以自动转换. 隐式类型转换 隐式类型转换: 由 C++ 编译系统自动完成的, 我们无需干预. 例如: int main() { int a = 6; a = a + 3.5; cout << a << en

  • JAVA中string数据类型转换详解

    在JAVA中string是final类,提供字符串不可以修改,string类型在项目中经常使用,下面给大家介绍比较常用的string数据类型转换: String数据类型转换成long.int.double.float.boolean.char等七种数据类型 复制代码 代码如下: * 数据类型转换 * @author Administrator * */ public class 数据类型转换 { public static void main(String[] args) { String c=

  • 有关C++继承与友元、继承与类型转换详解

    实例如下: #include <iostream> using namespace std; class a{ friend class pal; private: int i; protected: int j; public: int k; }; class b:public a{ protected: int l; }; class c:protected a{}; class d:private a{}; class e:public b{}; class pal{ public: v

  • JavaScript显式数据类型转换详解

    基本概念 将值从一种类型转换为另一种类型称为类型转换,类型转换总是返回基本类型值,如字符串.数字和布尔值,不会返回引用类型值. 类型转换分为"显式"和"隐式":"显式"转换发生在静态类型语言的编译阶段,而"隐式"转换则发生在动态类型语言的运行时. 显式类型转换 非字符串到字符串的类型转换 toString() 方法 数字.布尔值.字符串和对象都有 toString() 方法,但 null 和 undefined 没有. 例子:

  • Java之int和string类型转换详解

    int.String的类型转换 int -> String int i=12345; String s=""; 第一种方法:s=i+""; 第二种方法:s=String.valueOf(i); 这两种方法有什么区别呢?作用是不是一样的呢?是不是在任何下都能互换呢? String -> int s="12345"; int i; 第一种方法:i=Integer.parseInt(s); 第二种方法:i=Integer.valueOf(s

  • C++ 强制类型转换详解

    目录 一.C强制转换 二.C++强制转换 1.static_cast 静态转换(编译时检查) 2.const_cast 常量转换 3.reinterpret_cast 重新解释转换 4.dynamic_cast 动态转换(运行时检查) 三.要点总结 一.C强制转换 C语言中的强制转换主要用于普通数据类型.指针的强制转换,没有类型检查,转换不安全, 语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2(基本已经不用了) 二.C++强制

  • Python教程之类型转换详解

    目录 隐式类型转换 显式类型转换 Python 定义了类型转换函数以将一种数据类型直接转换为另一种数据类型,这在日常和竞争性编程中很有用.本文旨在提供有关某些转换函数的信息. Python中有两种类型转换: 隐式类型转换 显式类型转换 让我们详细讨论它们. 隐式类型转换 在 Python 中数据类型的隐式类型转换中,Python 解释器会自动将一种数据类型转换为另一种数据类型,而无需任何用户参与.要更清楚地了解该主题,请参阅以下示例. 例子: x = 10 print("x is of type

  • Java数据类型转换详解

    一.基本数据类型阐述 Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. [注]JAVA没有unsigned类型 (1). 整数:int,short,byte,long (2). 浮点型:float,double (3). 字符:char (4). 布尔:boolean 基本型别     大小         最小值            最大值 void boolean     -----         -----             

  • 关于Struts2的类型转换详解

    一.类型转换的意义 对于一个智能的MVC框架而言,不可避免的需要实现类型转换.因为B/S(浏览器/服务器)结构应用的请求参数是通过浏览器发送到服务器的,这些参数不可能有丰富的数据类型,因此必须在服务器端完成数据类型的转换 MVC框架是一个表现层解决方案,理应提供类型转换的支持,Struts2提供了功能非常强大的类型转换支持. 二.表现层数据的处理 1.对于web应用而言,表现层主要用于与用户交互,包括收集用户输入数据,向用户呈现服务器的状态.因此表现层的数据的流向主要有两个方向:输入数据和输出数

  • C#用户定义类型转换详解

    C#用户定义类型转换 •用于自定义类和结构能够进行隐式转换和显示转换.例如:将一个自定义类类型转换成整型,浮点型等,反之亦然. C#提供隐式转换和显式转换 •隐式转换:编译器自动执行转换•显式转换:编译器只在使用显式转换运算符时才执行转换声明隐式转换的语法如下.注:所有用户定义转换必须使用public和static修饰符 复制代码 代码如下: public static implicit operator TargetType(SourceType Identifier){       ... 

随机推荐