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的更多相关文章

  1. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 操作符重载和隐式类型转换

    C#中,某些类型会定义隐式类型转换和操作符重载.Unity中,有些对象也定义了隐式类型转换和操作符重载.典型情况有:UnityEngine.Object.UnityEngine.Object的销毁是调 ...

  2. [VC]C++ operator 两种用法

    C++中的operator,有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换).下面分别进行介绍:   1.operato ...

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

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

  4. operator 的两种用法

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

  5. C++操作符operator的另一种用法

    http://blog.csdn.net/memewry/article/details/7833314 参考地址 今天在程序员面试宝典上看到这样一道题目:  A C++ developer want ...

  6. Service的两种用法及其生命周期

    先来一点基础知识: Service 是android的四大组件之一,与Activity同属于一个级别,它是运行在后台进行服务的组件(例如在后台播放的音乐,播放音乐的同时并不影响其他操作).Servic ...

  7. JSP中的include的两种用法

    1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...

  8. 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。

    子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...

  9. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

随机推荐

  1. mysql 报错max_allowed_packet处理办法

    首先打开mysql管理工具执行 SHOW VARIABLES LIKE '%max_allowed_packet%'; 看到如图所示的效果 max_allowed_packet    1024slav ...

  2. 利用Ajax+MSMQ(消息队列)+WebService实现服务器端向客户端的信息推送

    需求: 每当数据库有数据更新时,推送到客户端 软需求: 1.服务器资源有限,要求资源占用尽可能小: 2.项目可控,不许调用第三方不可信不稳定的方法. 已有事例: 1.58到家采用的方法是TCP的长连接 ...

  3. 基于IE内核的浏览器:WebBrowser上的网页与Winform本身交互[Demo下载]

    http://blog.udnz.com/Article/Invoke_Javascript_On_Webbrowser_In_Winform.aspx C# 中调用 网页上的 Javascript ...

  4. 详解div+css相对定位和绝对定位用法

    1.定位的专业解释: (1)语法 position:static|absolute|fixed|relative 从上面语法可以看出,定位的方法有很多种,它们分别是静态(static),绝对定位(ab ...

  5. About SCCM 2012 UDA(User Device Affinity)

    Two useful articles about UDA: http://fbinotto.blogspot.com/2011/09/sccm-2012-user-device-affinity.h ...

  6. 【转载】 Spark性能优化指南——基础篇

    转自:http://tech.meituan.com/spark-tuning-basic.html?from=timeline 前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能 ...

  7. data process for large scale datasets

    Kmeans:   总体而言,速度(单线程): yael_kmeans > litekmeans ~ vl_kmeans 1.vl_kemans (win10 + matlab 15 + vs1 ...

  8. VIM-Sed常用的一些记录。。。逐渐学习。。

    :[range]co[py] {address} :t :[range]m[ove] {address] 例如 :1,3t10  1-3行复制到10行后.用m就是移动了. :sort / /   // ...

  9. ORACLE执行详解

    本文源自TTT BLOG,原文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html 简介:     本文全面详细介绍oracle执行计 ...

  10. 2016年中国大学生程序设计竞赛(合肥)-重现赛1001 HDU 5961

    传递 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...