c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换。对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式转换,我们下面就用以下这个小例子温故一下这两种用法:
#include <iostream>
#include <sstream>
using namespace std; class FuncObj
{
public:
FuncObj(int n): _n(n) {
cout << "constructor" << endl;
} bool operator()(int v) {
cout << "operator overload" << endl;
return v > _n;
} operator string() {
cout << "type convert" << endl;
stringstream sstr;
sstr << _n;
return sstr.str();
} int _n;
}; int main()
{
FuncObj obj();
if (obj())
cout << "11 greater than 10" << endl; string str(obj);
cout << str << endl;
}
第12行是操作符重载,重载()使得该对象成为一个函数对象,即该对象有类似函数的功能,在很多场合下可以当成函数指针使用,在STL的很多算法模板里广泛使用。FuncObj用过操作符重载可以判断传入的参数是否大于一个预先设定好的值(在构造函数里指定),见代码的29~31行。
17行的定义表名FuncObj对象可以隐身转换成string,这就是operator的第二个用法,使用方法见代码的33~34行。注意在函数声明时,operator关键词出现在返回类型的前面,区别与操作符重载时的用法。
上述代码的输出:
constructor
operator overload
greater than
type convert
顺便说点题外话,第33行把FuncObj类型的对象传入string的构造函数,是用了c++构造函数的隐式类型转换特性,虽然string类并没有显式定义参数为FuncObj的构造函数,但因为其可以隐式转换为string,所以语法上都是合法的。构造函数的隐式类型转换,是使用一个其他的类型构造当前类的临时对象并用此临时对象来构造当前对象,这种转换必须有构造函数的支持;operator算子的隐式类型转换,使用当前对象去生成另一个类型的对象(正好与构造函数隐式转换相反),这种转换必须有operator算子的支持。当然了,构造函数的隐式类型转换有利有弊,类的设计者就起决定性作用了,如果你不想让构造函数发生隐式的类型转换,请在构造函数前加explicit关键字;同时,operator算子声明的隐式类型转换也可以通过一些相应的返回值函数替代,用户的掌控性更好。
最后,用过实现一个经常发生的普遍需求(string转其他基本数据类型)让读者加深一下,operator自定义对象类型的隐式转换功能的用法。
template <typename T>
class string_cast
{
public:
string_cast(const std::string &from): m_from(from) {
}
operator T() const {
std::stringstream sstr(m_from);
T ret;
try {
sstr >> ret;
}
catch(std::exception &e)
{
return T();
}
return ret;
}
private:
const std::string &m_from;
};
string转int的用法:
cout << string_cast<int>("") << endl;
string转double的用法:
cout << string_cast<double>("12345.78") << endl;
是不是和c++的其他类型转换(static_cast,const_cast,dynamic_cast, reinterpret_cast)语法很相似?
c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast的更多相关文章
- 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 操作符重载和隐式类型转换
C#中,某些类型会定义隐式类型转换和操作符重载.Unity中,有些对象也定义了隐式类型转换和操作符重载.典型情况有:UnityEngine.Object.UnityEngine.Object的销毁是调 ...
- [VC]C++ operator 两种用法
C++中的operator,有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).下面分别进行介绍: 1.operato ...
- operator用法:隐式类型转换
operator它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换). 1.操作符重载C++可以通过operator实现重 ...
- operator 的两种用法
C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).1.操作符 ...
- C++操作符operator的另一种用法
http://blog.csdn.net/memewry/article/details/7833314 参考地址 今天在程序员面试宝典上看到这样一道题目: A C++ developer want ...
- Service的两种用法及其生命周期
先来一点基础知识: Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作).Servic ...
- JSP中的include的两种用法
1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...
- 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。
子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...
- Comparable和Comparator的区别&Collections.sort的两种用法
在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...
随机推荐
- 【Mocha.js 101】Mocha 入门指南
序 说到质量控制,不得不提起测试驱动开发(TDD)和行为驱动开发(BDD).随着敏捷软件开发的推行,软件质量控制的重担也逐渐从测试工程师转向了研发工程师.测试驱动也随之悄然而生,成为了敏捷开发中重要的 ...
- linux动态时钟探索
在早期的linux内核版本的时间概念都是由周期时钟提供的.虽然比较有效,但是,对于关注能耗电量的系统上,就不能满足长时间休眠的需求,因为周期系统要求必须在一定的频率下,周期性的处于活动状态.因此,li ...
- css3 视距-perspective
视距-用来设置用户与元素3d空间Z平面之间的距离. 实例1: HTML: <div class="perspective"> <h3&g ...
- JavaScript中本地对象、内置对象和宿主对象
链接:http://www.cnblogs.com/luckyXcc/p/5892896.html(Milk.╮的博客园提供) 其中内置对象只有两种:ECMA-262 只定义了两个内置对象,即 Glo ...
- OGRE 1.9 的第一个程序(OGRE HelloWorld程序)
平台:win7, VS2010 先看运行结果吧: 1. 安装OGRE 下载OGRE SDK 1.9,解压,放在你喜欢的地方,在OGRE SDK文件加下创建“OGRE_HOME.bat.bat”文本文件 ...
- android 保存文件的各种目录列表
一般的,我们可以通过context和Environment来获取要保存文件的目录 ($rootDir) +- /data -> Environment.getDataDirectory() | ...
- libevent之丢失header问题
本文为原创,转载请注明:http://www.cnblogs.com/gistao/ 背景 分享一个hhvm使用http server方式来处理请求的问题及对应的patch.hhvm3+版本支持fas ...
- 前台给后台传JSON字符串,后台解析并保存
前台 function BMSure() { var DanWeiName = $("[id$='BusinessName']").val(); var Address = $(& ...
- Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules的解决办法
前提:用eclipse做项目,新建“Dynamic Web Project”时,“Dynamic web module version”栏里选了3.0版本,部署项目的时候出现了如题的错误. 解决办法: ...
- 补交作业——Beta发布评论
1.飞天小女警: 礼物挑选这一项目是很好的点子,比较能够吸引客户,更加方便快捷的挑选也满足现代人在送礼物方面的需求.这一次的发布界面效果好了很多,并且成功的发布到了云服务器上. 2.nice! : 这 ...