c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast

C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换。对于操作符的重载,许多人都不陌生,但是估计不少人都不太熟悉operator的第二种用法,即自定义对象类型的隐式转换,我们下面就用以下这个小例子温故一下这两种用法:

 1 #include <iostream>
 2 #include <sstream>
 3 using namespace std;
 4
 5 class FuncObj
 6 {
 7 public:
 8   FuncObj(int n): _n(n) {
 9     cout << "constructor" << endl;
10   }
11
12   bool operator()(int v) {
13     cout << "operator overload" << endl;
14     return v > _n;
15   }
16
17   operator string() {
18     cout << "type convert" << endl;
19     stringstream sstr;
20     sstr << _n;
21     return sstr.str();
22   }
23
24   int _n;
25 };
26
27 int main()
28 {
29   FuncObj obj(10);
30   if (obj(11))
31     cout << "11 greater than 10" << endl;
32
33   string str(obj);
34   cout << str << endl;
35 }  

第12行是操作符重载,重载()使得该对象成为一个函数对象,即该对象有类似函数的功能,在很多场合下可以当成函数指针使用,在STL的很多算法模板里广泛使用。FuncObj用过操作符重载可以判断传入的参数是否大于一个预先设定好的值(在构造函数里指定),见代码的29~31行。

17行的定义表名FuncObj对象可以隐身转换成string,这就是operator的第二个用法,使用方法见代码的33~34行。注意在函数声明时,operator关键词出现在返回类型的前面,区别与操作符重载时的用法。

上述代码的输出:

constructor
operator overload
11 greater than 10
type convert
10

顺便说点题外话,第33行把FuncObj类型的对象传入string的构造函数,是用了c++构造函数的隐式类型转换特性,虽然string类并没有显式定义参数为FuncObj的构造函数,但因为其可以隐式转换为string,所以语法上都是合法的。构造函数的隐式类型转换,是使用一个其他的类型构造当前类的临时对象并用此临时对象来构造当前对象,这种转换必须有构造函数的支持;operator算子的隐式类型转换,使用当前对象去生成另一个类型的对象(正好与构造函数隐式转换相反),这种转换必须有operator算子的支持。当然了,构造函数的隐式类型转换有利有弊,类的设计者就起决定性作用了,如果你不想让构造函数发生隐式的类型转换,请在构造函数前加explicit关键字;同时,operator算子声明的隐式类型转换也可以通过一些相应的返回值函数替代,用户的掌控性更好。

最后,用过实现一个经常发生的普遍需求(string转其他基本数据类型)让读者加深一下,operator自定义对象类型的隐式转换功能的用法。

 1   template <typename T>
 2   class string_cast
 3   {
 4   public:
 5     string_cast(const std::string &from): m_from(from) {
 6     }
 7     operator T() const {
 8       std::stringstream sstr(m_from);
 9       T ret;
10       try {
11         sstr >> ret;
12       }
13       catch(std::exception &e)
14       {
15          return T(0);
16       }
17       return ret;
18     }
19   private:
20     const std::string &m_from;
21   };

string转int的用法:

cout << string_cast<int>("12345") << endl;

string转double的用法:

cout << string_cast<double>("12345.78") << endl;

是不是和c++的其他类型转换(static_cast,const_cast,dynamic_cast, reinterpret_cast)语法很相似?

c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast

时间: 2024-10-25 19:33:39

c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast的相关文章

More Effective C++----(21)通过重载避免隐式类型转换

Item M21:通过重载避免隐式类型转换 (读这一节内容之前,建议回顾C++转换构造函数和隐式转换函数的相关知识.) 以下是一段代码,如果没有什么不寻常的原因,实在看不出什么东西: class UPInt { // unlimited precision public: // integers 类 UPInt(); UPInt(int value); ... }; //有关为什么返回值是const的解释,参见Effective C++ 条款21 const UPInt operator+(co

OpenCV中operator的隐式类型转换

c++ operator操作符的两种用法 重载和隐式类型转换 今天学习OpenCV源码的时候碰到这种写法: template<typename _Tp> operator std::vector<_Tp>() const; template<typename _Tp, int n> operator Vec<_Tp, n>() const; template<typename _Tp, int m, int n> operator Matx<

More Effective C++ 条款21 利用重载技术避免隐式类型转换

1. 正如条款19和条款20所言,临时对象的构造和析构会增加程序的运行成本,因此有必要采取措施尽量避免临时对象的产生.条款20介绍了一种用于消除函数返回对象而产生临时对象的方法——RVO,但它并不能解决隐式类型转换所产生的临时对象成本问题.在某些情况下,可以考虑利用重载技术避免隐式类型转换. 2. 考虑以下类UPInt类用于处理高精度整数: class UPInt{ public: UPInt(); UPInt(int value); ... }; const UPInt operator+(c

operator 的两种用法

C++,有时它的确是个耐玩的东东,就比如operator,它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换). 1.操作符重载C++可以通过operator实现重载操作符,格式如下:类型T operator 操作符 (),比如重载+,比如下面这个例子template<typename T> class A{public:     const T operator+(const T& rhs)     {  

java中super 的两种用法

通过用 static 来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于 C 语言中的全局函数和全局变量.但是,并不是说有了这种便利,你便可以随处使用,如果那样的话,你便需要认真考虑一下自己是否在用面向对象的思想编程,自己的程序是否是面向对象的. 好了,现在开始讨论 this&super 这两个关键字的意义和用法. 在 Java 中, this 通常指当前对象, super 则指父类的.当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用

JSP中的include的两种用法

1.两种用法 <@inlcude file ="header.jsp"/> 此时引入的是静态的jsp文件,它将引入的jsp中的源代码原封不动地附加到当前文件中,所以在jsp程序中使用这个指令的时候file里面的值(即要导入的文件)不能带多余的标签或是与当前jsp文件重复的东西.例如里面不要包含<html><body>这样的标签,因为是把源代码原封不动的附加过来,所以会与当前的jsp中的这样的标签重复导致出错. <jsp:include page

Android---24---Spinner的两种用法

Spinner是一个列表选择框,它有两种用法: 一种是使用android:entries属性的,一种是不使用该属性,通过动态的添加Adapter来实现的. 第一种: MainActivity.java: import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import andr

jsp中include的两种用法

JSP中的include的两种用法 1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 <%@ include file=”relativeURI”%>                   是在翻译阶段执行 <jsp:include page=”relativeURI” flush=”true” />  在请求处理阶段执行. (2)引入内容的

include的两种用法之间的区别

以下是对include 两种用法的区别 主要有两个方面的不同; 一:执行时间上: <%@ include file="relativeURI"%> 是在翻译阶段执行 <jsp:include page="relativeURI" flush="true" /> 在请求处理阶段执行. 二:引入内容的不同: <%@ include file="relativeURI"%> 引入静态文本(html