C++面向对象高级编程(六)转换函数与non-explicit one argument ctor
技术在于交流、沟通,转载请注明出处并保持作品的完整性。
1.conversion function 转换函数
//1.转换函数
//conversion function
//只要你认为合理 你可以任意写转换函数
class Fraction
{
public:
Fraction(int num, int den = ):m_numerator(num),m_denominator(den){} operator double() const //注意看 没有返回类型,这个编译器会帮做,且防止我们声明错误 函数名就是返回类型
{
return ((double)m_numerator / m_denominator) ;//见下面自动转化规则
}
private:
int m_numerator;
int m_denominator;
}; int main(int argc, const char * argv[]) { Fraction f(,);
double d = + f; //先找全局函数 operator+ , 发现没有,再去找 发现在 Fraction内找到了
cout<< d << endl;
cout<<sizeof(double) << endl; return ;
}
自动转换遵循以下规则:
1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
a.若两种类型的字节数不同,转换成字节数高的类型
b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
3)所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4)char型和short型参与运算时,必须先转换成int型。
5)在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
例如:
上面的 return ((double)m_numerator / m_denominator) ;
如果声明成这样 (double) (m_numerator / m_denominator) 会执行int类型的除法运算
所以要先将两个int型参数的一个转换成double型参数即可
2.non-explicit one argument ctor
explicit的作用,防止隐式转换,一般作用于带参数的构造函数
class Fraction
{
public:
Fraction(int num, int den = ):m_numerator(num),m_denominator(den){} // Fraction operator+(const Fraction & f)
{
cout << f.m_numerator<<endl;
return f;
}
private:
int m_numerator;
int m_denominator;
}; int main()
{
Fraction f(,);
Fraction d = f + ;//调用时会使 4 隐式转换成 Fraction //调用的过程也是先去找f的operator+函数 找到了 调用
return ;
}
输出结果

Fraction d = f + 4; 这个函数的意义是 f调用operator+ 参数为4
而接受端
你会发现4被隐式转换成 Fraction
Fraction operator+(const Fraction & f){...}
参数4就被隐式转换成Fraction
那么加上 explicit
class Fraction
{
public:
explicit Fraction(int num, int den = ):m_numerator(num),m_denominator(den){} // Fraction operator+(const Fraction & f)
{
cout << f.m_numerator<<endl;
return f;
}
private:
int m_numerator;
int m_denominator;
};
调用端

上面我提到两次 调用过程 那么如果将operator+ 与 operator double() 连用的话会发生什么情况
class Fraction
{
public:
/*explicit*/ Fraction(int num, int den = ):m_numerator(num),m_denominator(den){} // Fraction operator+(const Fraction & f)
{
cout << f.m_numerator<<endl;
return f;
} operator double() const //注意看 没有返回类型,这个编译器会帮做,且防止我们声明错误 函数名就是返回类型
{
return ((double)m_numerator / m_denominator) ;//见下面自动转化规则
}
private:
int m_numerator;
int m_denominator;
};
编译会报错

参照<<侯捷 C++面向对象高级编程>>
C++面向对象高级编程(六)转换函数与non-explicit one argument ctor的更多相关文章
- C++面向对象高级编程(七)point-like classes和function-like classes
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 ...
- C++面向对象高级编程(五)类与类之间的关系
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming OOP面向对象编 ...
- C++面向对象高级编程(九)Reference与重载operator new和operator delete
摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一 Reference 引用:之前提及过,他的主要作用就是取别名,与指针很相似,实现也是基于指针. 1.引用必须有初值,且不能引用nul ...
- C++面向对象高级编程(八)模板
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明 1.成员模板 成员模板:参数为tem ...
- C++面向对象高级编程(四)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...
- C++面向对象高级编程(三)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...
- C++面向对象高级编程(二)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 知识点1.重载成员函数 知识点2 . return by value, return by reference 知识点3 重载非成员函数 ...
- C++面向对象高级编程(一)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要: 知识点1 构造函数与析构函数 知识点2 参数与返回值 知识点3 const 知识点4 函数重载(要与重写区分开) 知识点5 友元 先以C ...
- C++面向对象高级编程(下)第一周-Geekband
勿在浮沙筑高台 革命尚未成功,同志仍需努力 <h1> Conversion Function</h1> class Fraction { public: Fraction(in ...
随机推荐
- PHP递归算法
/** * 获取菜单 * @param number $id * @return multitype: */ public function menu($id = 0) { $menu = M ( ' ...
- [.net基础]访问修饰符
标题:[.net基础]访问修饰符 一.前言 基础掌握不牢固啊,所以记录下来. 二.方法访问修饰符Internal (1).创建工程ParentAndSon (2).添加类ModelA namespac ...
- oracle导入时报错
之前在oracle数据库中新建了一个表空间和用户,在新建的用户下导入".dmp"文件是出现了这个错误. 解决方法: 使用管理员登陆进去,创建一个对应的表空间和用户,就OK了. (表 ...
- 20145302张薇《Java程序设计》实验二报告
20145302张薇<Java程序设计>实验二:Java面向对象程序设计 使用TDD的方式设计实现复数类:Complex 测试代码 import org.junit.Test; publi ...
- linux块设备读写流程
在学习块设备原理的时候,我最关系块设备的数据流程,从应用程序调用Read或者Write开始,数据在内核中到底是如何流通.处理的呢?然后又如何抵达具体的物理设备的呢?下面对一个带Cache功能的块设备数 ...
- nxp的layerscape系列芯片中的rcw指定了一些什么信息
答:指定了一些可以配置的硬件信息(如可以配置uart相关的引脚功能).引导镜像(uboot)的读取地址以及从何种介质(flash,sd)启动系统的信息
- Putting Apache Kafka To Use: A Practical Guide to Building a Stream Data Platform-part 2
转自: http://confluent.io/blog/stream-data-platform-2 http://www.infoq.com/cn/news/2015/03/ap ...
- RK61 Keyboard Use
~ 打法: FN+shift+Esc / ? Alt Files Ctral <=> 上 下 左 右 打法:FN+shift 切换 解锁键盘 打法:FN+win 蓝牙连接 打法:FN+ ...
- PHP5.6版本安装redis扩展
一.php安装redis扩展 1.使用phpinfo()函数查看PHP的版本信息,这会决定扩展文件版本 2.根据PHP版本号,编译器版本号和CPU架构, 选择php_redis-2.2 ...
- web页面中 将几个字段post提交
思路 自己在html中构建form 先根据传入的action构建form的action 然后根据要提交的字段构建form中的元素 最后通过调用form中的按钮提交from表单 方法:var jsP ...