C++隐式类型转换
2015-09-26 12:47
253 查看
C++ primer 中有这么一句话:可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。
这么解释:
比如有个类A的对象a的成员函数的参数应该是类A的对象,但是把一个别的类型B的对象b传进去了,而且这个对象b的类型恰好是A的单参数构造函数参数类型,这时系统就用这个b自作聪明的创建了一个类A的临时对象c,虽然c和a都是A类型,但是是不同的对象。
这种隐式转换有很大风险,可以用explicit加在单参数构造函数前来避免这种类类隐形转换。
我个人认为这就是一种人为使用错误,而编译器又恰恰没有指出。
输出结果:
如果我们加上explicit则会报错:
explicit Fruit(const string& nst, const string& cst = "green") :name(nst), colour(cst){}
这是因为上面那句话禁止了隐式转换。
你会发现最后的使用上,我们用一个string类型作一个期待Fruit类形参的函数的参数,结果竟然得出了是true(1),不要感到奇怪,这就是我现在要讲的东西,隐式类类型转换:“可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。”(C++
Primer)
首先要单个实参,你可以把构造函数colour的默认实参去掉,也就是定义一个对象必须要两个参数的时候,文件编译不能通过。然后满足这个条件后,系统就知道怎么转换了,不过这里比较严格
以前我们构造对象的时候Fruit apple("apple")其实也已经有了一个转换,从const char *的C字符串格式,转为string,在这里,你再apple.isSame("apple")的话,蠢系统不懂得帮你转换两次,所以你必须要用 string()来先强制转换,然后系统才知道帮你从string隐式转换为Fruit,当然其实你自己也可以帮他完成。 cout<<"apple = /"apple/" ?:"<<apple.isSame(Fruit("apple"));这样。Fruit
apple = Fruit("apple"); //定义一个Fruit类对象apple。也就是这样转换的。不过这就叫显式转换了,我们不标出来,系统帮我们完成的,叫隐式的呗。
这里要说的是,假如你显示转换就可以不管有多少参数了,比如在前面提到的必须需要两个参数的构造函数时的例子。
这么解释:
比如有个类A的对象a的成员函数的参数应该是类A的对象,但是把一个别的类型B的对象b传进去了,而且这个对象b的类型恰好是A的单参数构造函数参数类型,这时系统就用这个b自作聪明的创建了一个类A的临时对象c,虽然c和a都是A类型,但是是不同的对象。
这种隐式转换有很大风险,可以用explicit加在单参数构造函数前来避免这种类类隐形转换。
我个人认为这就是一种人为使用错误,而编译器又恰恰没有指出。
#include <string> #include <iostream> using namespace std; class Fruit //定义一个类,名字叫Fruit { string name;//定义一个name成员 string colour;//定义一个colour成员 public: bool isSame(const Fruit& otherFruit)//期待的形参是另一个Fruit类对象,测试是否同名 { return name == otherFruit.name; } void print()//定义一个输出名字的成员print() { cout << colour << " " << name << endl; } Fruit(const string& nst, const string& cst = "green") :name(nst), colour(cst){} Fruit(){} }; int main() { Fruit apple("apple"); Fruit orange("orange"); cout << "apple = orange? : " << apple.isSame(orange) << endl; //隐式转换 cout << "apple = apple? :" << apple.isSame(string("apple")) << endl; return 0; }
输出结果:
如果我们加上explicit则会报错:
explicit Fruit(const string& nst, const string& cst = "green") :name(nst), colour(cst){}
这是因为上面那句话禁止了隐式转换。
你会发现最后的使用上,我们用一个string类型作一个期待Fruit类形参的函数的参数,结果竟然得出了是true(1),不要感到奇怪,这就是我现在要讲的东西,隐式类类型转换:“可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。”(C++
Primer)
首先要单个实参,你可以把构造函数colour的默认实参去掉,也就是定义一个对象必须要两个参数的时候,文件编译不能通过。然后满足这个条件后,系统就知道怎么转换了,不过这里比较严格
以前我们构造对象的时候Fruit apple("apple")其实也已经有了一个转换,从const char *的C字符串格式,转为string,在这里,你再apple.isSame("apple")的话,蠢系统不懂得帮你转换两次,所以你必须要用 string()来先强制转换,然后系统才知道帮你从string隐式转换为Fruit,当然其实你自己也可以帮他完成。 cout<<"apple = /"apple/" ?:"<<apple.isSame(Fruit("apple"));这样。Fruit
apple = Fruit("apple"); //定义一个Fruit类对象apple。也就是这样转换的。不过这就叫显式转换了,我们不标出来,系统帮我们完成的,叫隐式的呗。
这里要说的是,假如你显示转换就可以不管有多少参数了,比如在前面提到的必须需要两个参数的构造函数时的例子。
int main() { Fruit apple("apple", "green"); Fruit orange("orange", "yellow"); cout << "apple = orange? : " << apple.isSame(orange) << endl; //显示转换 cout << "apple = /"apple/"? :" << apple.isSame(Fruit("apple", "green")) << endl; return 0; }
相关文章推荐
- 《C++primer(第五版)》学习之路-第十一章:关联容器
- 关于计算struct结构体占用空间
- C语言实现变长数组
- c++primer plus第十四章-多重继承、模板类
- 解码
- Stick
- VC++ 下FFT试验
- C++文件中读单词并统计输出改单词及其个数
- C++ string类型的split字符串分割函数
- C++ Primer Plus第六版 第十一章 编程练习答案
- C++的几种强制类型转换
- C++ 虚函数表解析
- C/C++笔试准备(1)
- C语言中 .h文件和.c文件的区别
- C语言复习day2
- c的free和c++的delete的区别
- C语言里面 sizeof 的使用
- c/c++程序调试
- C++中的头文件和源文件
- C语言复习day1