什么是隐式转换?

众所周知,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
inta = true; (bool类型被转换为int类型)
int* ptr = null;(null被转换为int*类型)

函数参数传值。例如:

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

函数返回值。例如:

1
2
3
4
doubleadd(inta, intb)
{
    returna + 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
classTest
{
public:
  Test(inta);
  boolisSame(Test other)
  {
    returnm_val == other.m_val;
  }
private
  intm_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; 

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

c++隐式类型转换和explicit的更多相关文章

  1. 【C++】隐式类型转换和 explicit关键字

    来自:黄邦勇帅 1. 当类中带有一个参数的构造函数时,将执形对象的隐式转换,比如有类 A,有一个带有一个参数的构造函数A(int i){}则当出现语句A m=1;就会调用带有一个参数的构造函数来创建对 ...

  2. 21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数

    ++操作符重载 ++操作符分为前置++和后置++,比如: ++a;  a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 ...

  3. 从Qt谈到C++(一):关键字explicit与隐式类型转换

    转载:果冻虾仁 提出疑问 当我们新建了一个Qt的widgets应用工程时.会自动生成一个框架,包含了几个文件. 其中有个mainwindow.h的头文件.就是你要操纵的UI主界面了.我们看看其中的一段 ...

  4. c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast

    C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换.对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式 ...

  5. C++的隐式类型转换与转换操作符

    C++标准允许隐式类型转换,即对特定的类,在特定条件下,某些参数或变量将隐形转换成类对象(创建临时对象).如果这种转换代价很大(调用类的构造函数),隐式转换将影响性能.隐式转换的发生条件:函数调用中, ...

  6. 【M21】利用重载技术避免隐式类型转换

    1.考虑UPint 的加法+,UPint a, b, result; 为了使result = a+10; result= 10+a; 都能通过编译,操作符重载如下: const UPint opera ...

  7. operator用法:隐式类型转换

    operator它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换). 1.操作符重载C++可以通过operator实现重 ...

  8. C++ 中operator用法:隐式类型转换

    [转]C++ operator两种用法 C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator c ...

  9. C++进阶--隐式类型转换

    //############################################################################ /* 隐式类型转换 * * 类型转换可分为 ...

随机推荐

  1. ubuntu - 安装hive

    粗略步骤: 详细参考:https://www.2cto.com/net/201804/735478.html 环境:ubunut  jdk  hadoop   mysql 一.下载hive 二.解压( ...

  2. [比赛|考试]nowcoder NOIPpj组第二场

    nowcoder NOIPpj组第二场 370pts/400pts(100,100,100,70) rank3 给自己的反思:前3题都A了,T4O(N^2)不会就是不会(没准是我懒得推了),DP了70 ...

  3. C++基础学习2:命名空间

    C++语言引入命名空间(Namespace)这一概念主要是为了避免命名冲突,其关键字为 namespace. 科技发展到如今,一个系统通常都不会仅由一个人来开发完成,不同的人开发同一个系统,不可避免地 ...

  4. 洛谷P3507 [POI2010]GRA-The Minima Game

    题目描述 Alice and Bob learned the minima game, which they like very much, recently. The rules of the ga ...

  5. C. The Fair Nut and String 递推分段形dp

    C. The Fair Nut and String 递推分段形dp 题意 给出一个字符串选择一个序列\({p_1,p_2...p_k}\)使得 对于任意一个\(p_i\) , \(s[p_i]==a ...

  6. Eclipse导入GitHub项目两处报错处理

    1.项目出现Could not calculate build plan:pligin 错误解决办法: 删除本地.m2仓库中 org.apache.maven.plugins:maven-resour ...

  7. Xcode上传appstore 出现 Found an unexpected Mach-O header code: 0x72613c21 错误

    网上说是静态库的问题

  8. Ubuntu server 修改系统时区

    执行命令: sudo dpkg-reconfigure tzdata

  9. 小a与黄金街道(欧拉函数+快速幂)

    链接:https://ac.nowcoder.com/acm/contest/317/D 来源:牛客网 题目描述 小a和小b来到了一条布满了黄金的街道上.它们想要带几块黄金回去,然而这里的城管担心他们 ...

  10. 2015苏州大学ACM-ICPC集训队选拔赛(1) 1001 1002 1010

    签到题 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissio ...