http://blog.csdn.net/chenyiming_1990/article/details/8862497

1.对于系统的预定义基本类型数据,C++提供了两种类型转换方式:隐式类型转换和显式类型转换。

  1. int a=5,sum;
  2. double b=5.55;
  3. sum=a+b;//-------(1)
  4. std::cout<<"隐式转换:a+b="<<sum<<std::endl;
  5. sum=(int)(a+b);//-------(2)
  6. sum=int(a+b);//-------(3)
  7. std::cout<<"显式转换:a+b="<<sum<<std::endl

上述代码中的(1)就是含有隐式类型转换的表达式,在进行"a+b"时,编译系统先将a的值5转换为双精度double,然后和b相加得到10.55,在向整形变量sum赋值时,将10.55转换为整形数10,赋值为变量sum。这种转换是C++编译系统自动完成,不需要用户去干预。而上例中的(2)和(3)中则涉及到了显式类型转换,它们都是把a+b所得结果的值,强制转化为整形数。只是(2)式是C语言中用到的形式:(类型名)表达式,而(3)式是C++中的采用的形式:类型名(表达式);

2.那么对于用户自定义的类类型而言,有该如何去实现它们和其他数据类型之间的转换呢,C++中提供了两种方法:

(1)通过转换构造函数进行类型转换;

(2)通过类型转换函数进行类型转换;

毫无疑问转换构造函数就是构造函数的一种,只不过它拥有类型转换的作用罢了。是否记得在C++之运算重载符(1)中两个复数(sum=com1+com2)相加的实例,现在如果我想要实现sum=com1+5.5,那该怎么办,也许你首先会想到再定义一个关于复数加双精度的运算符重载函数。这样做的确可以。另外我们还可以定义一个转换构造函数来解决上述的问题。我们对Comlex类(复数类)进行这样改造:

  1. #include <iostream>
  2. class Complex //复数类
  3. {
  4. private://私有
  5. double real;//实数
  6. double imag;//虚数
  7. public:
  8. Complex(double real,double imag)
  9. {
  10. this->real=real;
  11. this->imag=imag;
  12. }
  13. Complex(double d=0.0)//转换构造函数
  14. {
  15. real=d;//实数取double类型的值
  16. imag=0;//虚数取0
  17. }
  18. Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);
  19. void showComplex();
  20. };
  21. Complex Complex::operator+(Complex com1)
  22. {
  23. return Complex(real+com1.real,imag+com1.imag);
  24. }
  25. void Complex::showComplex()
  26. {
  27. std::cout<<real;
  28. if(imag>0)
  29. std::cout<<"+";
  30. if(imag!=0)
  31. std::cout<<imag<<"i"<<std::endl;
  32. }
  33. int main()
  34. {
  35. Complex com(10,10),sum;
  36. sum = com + 5.5;//5.5调用Complex(5.5)生成临时对象,它的复数是5.5+0i
  37. sum.showComplex();//输出运算结果
  38. return 0;
  39. }

结果:

15.5 + 10i

上述代码在执行5.5时,调用了转换构造函数,将double类型的5.5转换为无名的Complex类的临时对象(5.5+0i),然后执行两个Complex类(复数类)对象相加的运算符重载函数。所以说一般的转换构造函数的定义形式:

  类名(待转换类型)

  {

    函数体;

  }

转换构造函数不仅可以将预定义的数据类型转换为自定义类的对象,也可以将另一个类的对象转换成转换构造函数所在的类的对象。

  转换构造函数可以把预定义类型转化为自定义类的对象,但是却不能把类的对象转换为基本数据类型。比如:不能将Complex类(复数类)的对象转换成double类型数据。于是在C++中就用类型转换函数来解决这个问题。定义类型转换函数一般形式:

  operator 目标类型()

  {

    ...

    return 目标类型的数据;

  }

目标类型是所要转化成的类型名,既可以是预定义及基本类型也可以是自定义类型。

类型转换函数的函数名(operator 目标类型)前不能指定返回类型

没有参数

但在函数体最后一条语句一般为return语句,返回的是目标类型的数据。

现在我们对Complex类做类似改造:

  1. #include <iostream>
  2. class Complex //复数类
  3. {
  4. private://私有
  5. double real;//实数
  6. double imag;//虚数
  7. public:
  8. Complex(double real,double imag)
  9. {
  10. this->real=real;
  11. this->imag=imag;
  12. }
  13. Complex(double d=0.0)//转换构造函数
  14. {
  15. real=d;//实数取double类型的值
  16. imag=0;//虚数取0
  17. }
  18. Complex operator+(Complex com1);//或friend Complex operator+(Complex com1,Complex com2);
  19. void showComplex();
  20. operator double();
  21. };
  22. Complex Complex::operator+(Complex com1)
  23. {
  24. return Complex(real+com1.real,imag+com1.imag);
  25. }
  26. void Complex::showComplex()
  27. {
  28. std::cout<<real;
  29. if(imag>0)
  30. std::cout<<"+";
  31. if(imag!=0)
  32. std::cout<<imag<<"i"<<std::endl;
  33. }
  34. Complex::operator double()
  35. {
  36. return real;
  37. }
  38. int main()
  39. {
  40. Complex com(10,10);
  41. double total1,total2;
  42. total1 = double(com) + 5.5;//double(com)把复数(10+10i)转换为双精度数10.0
  43. total2 = 5.5 + com; // 写成 total2 = com + 5.5 是错误的
  44. std::cout<<"把Complex类显式对象转化为double类型与5.5相加为:"<< total1 << std::endl;
  45. std::cout<<"把Complex类对象隐式转化为double类型与5.5相加为:"<< total2 << std::endl;
  46. return 0;
  47. }

说明:

total2 = 5.5 + com;  com自动调用转换函数进行转换(如果5.5 改为5,并且还定义有operator long() 类型转换,将出现编译错误,因为int 既可以转换为long ,也可以转换为 double,编译器会报错)。

为什么  total2 = com  + 5.5; 不行呢?

这是会出现歧义:

是com 用转换函数变为double型,进行double定义的加法

还是 5.5 利用转换构造函数变为Complex临时变量,进行 Complex定义的加法,就不清楚了

所以进行显示的转换:

  1. total = (double)com + 5.5

3.最后对类型转换函数做几点补充:

(1)类型转换函数只能作为类的成员函数,不能定义为类的友元函数;

(2)类型转换函数中必须有return语句,即必须送回目标类型的数据作为函数返回值;

(3)一个类可以定义多个类型转换函数,C++编译器会根据函数名来自动调用相应的类型转换函数函数

C++ 构造转换函数和强制转换函数的更多相关文章

  1. JAVA数据类型自动转换,与强制转换

    一.数据类型自动转换 public class Test{ public static void main(String[] args){ int a = 1; double b = 1.5; dou ...

  2. Number 强制类型转换 int 强制转换整型 float 强制转换浮点型 complex 强制转换成复数 bool 强制转换成布尔类型,结果只有两种,要么True 要么 False """bool 可以转换所有的数据类型 everything"""

    # ###Number 强制类型转换 var1 = 5 var2 = 4.85 var3 = True var3_2 = False var4 = 3+9j var5 = "888777&q ...

  3. 编写高质量代码改善C#程序的157个建议[正确操作字符串、使用默认转型方法、却别对待强制转换与as和is]

    前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理解的东西,有些地方可能理解的不太到位,还望指正. 建议1. ...

  4. [Effective JavaScript 笔记]第59条:避免过度的强制转换

    js是弱类型语言.许多标准的操作符和代码库会把输入参数强制转换为期望的类型而不是抛出错误.如果未提供额外的逻辑,使用内置操作符的程序会继承这样的强制转换行为. functin square(x){ r ...

  5. C#高级编程9-第7章 运算符和类型强制转换

    运算符和类型强制转换 1.运算符 运算符的简化操作 条件运算符: if-else的简化操作,也称三元运算符.如果条件为真,返回一个值,为假返回另外一个值. condition?true_value:f ...

  6. C#程序编写高质量代码改善的157个建议[正确操作字符串、使用默认转型方法、却别对待强制转换与as和is]

    前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理解的东西,有些地方可能理解的不太到位,还望指正. 建议1. ...

  7. 3_PHP表达式_5_数据类型转换_类型强制转换

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. PHP类型转换分为类型自动转换和类型强制转换. 3.5.2 类型强制转换 类型强制转换允许编程人员手动将变量的数据 ...

  8. 如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南)

    如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南) 由于对象是多态的,因此基类类型的变量可以保存派生类型.若要访问派生类型的方法,需要将值强制转换回该派生类型.不过,在这些情况下, ...

  9. C#中 As 和强制转换的总结

    1.1.1 摘要 C#是一门强类型语言,一般情况下,我们最好避免将一个类型强制转换为其他类型,但有些时候难免要进行类型转换. 先想想究竟哪些操作可以进行类型转换(先不考虑.NET提供的Parse),一 ...

随机推荐

  1. nodejs之socket.io 私发消息和选择群组发消息

    写在前面:其实有的时候忙碌是好的,比如忙碌起来的自己手机可以一天耗费掉只有20%的电,忙碌的自己很专心于一件事情,但是忙碌不等于过度疲劳,本周忙碌有点上脑,迷糊了一天,都在补觉,还是要去平衡下自己一天 ...

  2. 2016424王启元 Exp5 msf基础应用

    成功实现的有: 一个主动攻击实践,ms08_067 一个针对浏览器的攻击,ms11_050 一个针对客户端的攻击,Adobe(在实现这一步骤的时候有点小瑕疵,就是Adobe的版本问题换了三四个才成功) ...

  3. Dijkstra算法以及各种海量数据排序算法

    一.Dijkstra最短路径算法 是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 实现一 // // D ...

  4. MySQL 的更新操作update

    1 更新操作(单表更新) 1)单表更新 update [low_priority] [ignore] table_reference set col_name1={expr1|default},col ...

  5. 网站Http升级至Https(基于Tomcat)

    由于之前一直忙于服创比赛,然后就导致好久没写博客了. 现在服创结束也有十来天了,感觉不写点什么就对不起自己了. 于是乎,就写写将网站从http升级到https的过程吧. 首先域名和服务器自然是必须的, ...

  6. H5页面JS调试

    页面调试 常用的调试方法 开发时候的调试基本是在chrome的控制台Emulation完成 现有的一些手机端调试方案: Remote debugging with Opera Dragonfly 需要 ...

  7. Eclipse/MyEclipse 选择Android NDK目录时提示“Not a valid NDK directory”

    Eclipse或者MyEclipse 选择Android NDK目录时提示“Not a valid NDK directory” 在NDK目录中新建一个名称 ndk-build (没有扩展名)的空文件

  8. JavaScript中类型检测

    文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般Js类型检测的方法,是构建Js知识体系的一小块,这篇文章是我很早之前总结的. 一. ...

  9. android studio应用修改到android源码中作为内置应用

    1. 方法一:导入,编译(太麻烦,各种不兼容问题) android studio和eclipse的应用结构目录是不同的,但是在android源码中的应用基本上都是使用的eclipse目录结构(在/pa ...

  10. first post

    post