什么是隐式转换?

众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。

所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换。

为什么要进行隐式转换?

C++面向对象的多态特性,就是通过父类的类型实现对子类的封装。

通过隐式转换,你可以直接将一个子类的对象使用父类的类型进行返回。

在比如,数值和布尔类型的转换,整数和浮点数的转换等。

某些方面来说,隐式转换给C++程序开发者带来了不小的便捷。

C++是一门强类型语言,类型的检查是非常严格的。

如果没有类型的隐式转换,这将给程序开发者带来很多的不便。

当然,凡事都有两面性,在你享受方便快捷的一面时,你不得不面对太过智能以至完全超出了你的控制。

风险就在不知不觉间出现。

C++隐式转换的原则

  • 基本数据类型 基本数据类型的转换以取值范围的作为转换基础(保证精度不丢失)。
    隐式转换发生在从小->大的转换中。比如从char转换为int。
    从int-》long。
  • 自定义对象 子类对象可以隐式的转换为父类对象。

C++隐式转换发生条件

  • 混合类型的算术运算表达式中。例如:

    ?

    1

    2

    3

    int a = 3;

    double b = 4.5;

    a + b; // a将会被自动转换为double类型,转换的结果和b进行加法操作

  • 不同类型的赋值操作。例如:

    ?

    1

    2

    int a = true; (bool类型被转换为int类型)

    int * ptr = null;(null被转换为int*类型)

  • 函数参数传值。例如:

    ?

    1

    2

    void func(double a);

    func(1); // 1被隐式的转换为double类型1.0

  • 函数返回值。例如:

    ?

    1

    2

    3

    4

    double add(int a, int b)

    {

        return a + b;

    } //运算的结果会被隐式的转换为double类型返回

#参考:http://developer.51cto.com/art/201002/183139.htm

#以上四种情况下的隐式转换,都满足了一个基本原则:低精度 –》 高精度转换。

不满足该原则,隐式转换是不能发生的。

当然这个时候就可以使用与之相对于的显式类型转换(又称强制类型转换),使用方法如下:
       double a = 2.0;
       int b = (int)a;

使用强制类型转换会导致精度的损失,因此使用时务必确保你已经拥有足够的把握。

隐式转换的风险

隐式转换的风险一般存在于自定义的类构造函数中。

按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象。

  • 例一
    如下面所示:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    class String

    {

    public:

        String ( const char* p ); // 用C风格的字符串p作为初始化值

        //…

    }

    String s1 = “hello”; //OK 隐式转换,等价于String s1 = String(”hello”)

    但是有的时候可能会不需要这种隐式转换,如下:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    class String

    {

    public:

        String ( int n ); //本意是预先分配n个字节给字符串

        String ( const char* p ); // 用C风格的字符串p作为初始化值

        //…

    }

    下面两种写法比较正常:
    String s2 ( 10 );   //OK 分配10个字节的空字符串
    String s3 = String ( 10 ); //OK 分配10个字节的空字符串

    下面两种写法就比较疑惑了:
    String s4 = 10; //编译通过,也是分配10个字节的空字符串
    String s5 = ‘a’; //编译通过,分配int(‘a’)个字节的空字符串
    s4 和s5 分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,容易令人误解。
    #参考:http://blog.csdn.net/smilelance/article/details/1528737

  • 例二
    如下例:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    class Test

    {

    public:

      Test(int a);

      bool isSame(Test other)

      {

        return m_val == other.m_val;

      }

    private

      int m_val;

    }

    如下调用:
    Test a(10);
    If(a.isSame(10)) //该语句将返回true

    本来用于两个Test对象的比较,竟然和int类型相等了。
    这里就是由于发生了隐式转换,实际比较的是一个临时的Test对象。
    这个在程序中是绝对不能允许的。

禁止隐式转换

既然隐式转换存在这么多的风险,那如何能够禁止隐式转换的发生呢。

C++中提供了explicit关键字,在构造函数声明的时候加上explicit关键字,能够禁止隐式转换。使用方法如下:

?

1

2

3

4

5

6

class Test

{

explicit Test(int a);

……

}

加上该关键字以后,如下的操作是合法的:

?

1

Test(10);

如下的操作就变成非法的了:

?

1

Test aa = 10; 

这样就可以有效的防止隐式转换的发生,从而能够对程序进行精确控制,达到提高品质的目的。

芭蕉树上第十七根芭蕉-- 隐式转换相关推荐

  1. 令人炸毛儿的MySQL隐式转换 - 无形之刃,最为致命

    小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL江湖路 | 专栏目录   我相信90%以上的同学们在平时开发时,或多或少都被隐式转换(CONVERT_IMPLICIT)坑过,甚至测出bug ...

  2. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

    目录 隐式转换和隐式参数 隐式转换 自动导入隐式转换方法 隐式转换的时机 隐式参数 隐式转换和隐式参数 隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能.我们可以很 ...

  3. C++拾趣——类构造函数的隐式转换

    之前看过一些批判C++的文章,大致意思是它包含了太多的"奇技淫巧",并不是一门好的语言.我对这个"奇技淫巧"的描述颇感兴趣,因为按照批判者的说法,C++的一些特 ...

  4. Java Script 第四节课 Java Script的隐式转换

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. mysql 隐式失误_评“MySQL 隐式转换引起的执行结果错误”

    今天看到一篇关于MySQL隐式转换引发执行结果错误的文章: ====================================================================== ...

  6. 隐式转换和显式转换及强制转换的区别

    string strType = "123"; object objType= (object)strType;//可以不要,隐式转换, 要的为显式转换 string strTyp ...

  7. mysql数据库隐式表_详解MySQL数据库常见的索引问题:无索引,隐式转换,附实例说明...

    概述 在这些年的工作之中,由于SQL问题导致的数据库故障层出不穷,而索引问题是SQL问题中出现频率最高的,常见的索引问题包括:无索引,隐式转换. 索引问题 1.无索引 当数据库中出现访问表的SQL无索 ...

  8. MySQL和Oracle中的隐式转换

    今天在处理一个问题的时候,需要根据其他部门提供的sql语句对一个表中的数据进行了筛查. 语句类似下面的形式 > SELECT MAX_LEVEL,LOGOUT_TIME,CURRENT_DATE ...

  9. C#中数据类型转换-隐式转换

    隐式转换:一般是低类型向高类型转化,能够保证值不发生变化. 隐式数值转换: 从 sbyte 到 short.int.long.float.double 或 decimal. 从 byte 到 shor ...

  10. mysql隐式转换造成索引失效的事故总结

    隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给mysql,这样 ...

最新文章

  1. linux编程技术进程代码,Linux进程通信—信号量 代码实现
  2. mod_pagespeed
  3. linux中终端字符界面打印QQ,教你如何在开发驱动时在图形界面下的终端打印字符!!...
  4. 机器学习_的应用网站记录01_可以上色的网站
  5. ligerui layout拖动中间分隔条宽度后,重新调整两边控件的宽度
  6. 微信小程序-智能机器人
  7. 如何给 mongodb 设置密码
  8. 性能优越的轻量级日志收集工具,微软、亚马逊都在用!
  9. java调用nodejs程序,从java里面调用node.js脚本
  10. 《深入理解 Spring Cloud 与微服务构建》第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统
  11. Git 修改已提交 commit 的信息
  12. 数据库 ER图 EER图(鸭蹼图) freedgo绘图工具
  13. 进共享服务器提示信号灯超时,移动硬盘提示说无法访问,信号灯超时,时间已到是为什么啊...
  14. html js打开一个新页面跳转,js页面跳转
  15. 战投之王:蔡崇信、刘炽平和刘德的精密战争
  16. 互联网从此没有 BAT
  17. 嵌入式linux指纹识别项目,基于嵌入式应用平台的指纹识别系统设计
  18. matlab里调节触发角度,电机与拖动基础及MATLAB仿真陈亚爱第4章直流电机.ppt
  19. 《RSSHub Radar》可以帮助你快速发现和订阅当前网站RSS的浏览器扩展
  20. 利用随机森林进行特征重要性排序

热门文章

  1. 绘制自己的人际关系图_matlab能绘制人际关系网络图吗?
  2. 情人年-CGArt | 风格 银光版
  3. 计算机术语 gc 是什么意思,GC是什么?为什么我们要去使用它
  4. 牛客练习赛47 D DongDong坐飞机 (分层最短路)
  5. ubuntu20.04中安装划词翻译_中英文文档翻译
  6. 计算机无法进入操作系统怎么办,老司机教你电脑开机无法进入系统怎么办
  7. 创建Qsys_PIO IP核
  8. Unity 3D课程总结
  9. 微信小程序: 赞赏码的长按识别
  10. 以休闲游戏“植物大战僵尸”为例,制作无限阳光修改器。