C++中operator的两种用法

首先声明,转载自:http://blog.csdn.net/skdkjzz/article/details/45872801

 

转换函数的名称是类型转换的目标类型,因此,不必再为它指定返回值类型;转换函数是被用于本类型的数值或变量转换为其他的类型,也不必带参数

 

在写这篇文章之前,让我们先回顾一下编译器通过匹配过程确定调用哪一个函数的匹配顺序:
(1)寻找和使用最符合函数名和参数类型(包括返回值)的函数,若找到则调用;

(2)否则,寻找一个函数模板,将其实例化产生一个匹配的重载函数,若找到则调用;

(3)否则,寻找可以通过类型转换进行参数匹配的重载函数,若找到则调用它。


如果以上步骤均未找到匹配函数,则这个调用是错误的;如果这个调用有多于一个的匹配选译,则调用匹配出现二义性,也是错误的。
  
类型转换是将一种类型的值映射为另一种类型的值。类型转换实际上包含有自动隐含和强制的两种。

C语言编译系统提供的内部数据类型的自动隐式转换规则如下:

1.程序在执行算术运算时,低类型可以转换为高类型。

2.在赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给它。

3.当在函数调用时,将实参值赋给形参,系统隐式地将实参转换为形参的类型后,赋给形参。

4.函数有返回值时,系统将自动地将返回表达式类型转换为函数类型后,赋值给调用函数。


在以上情况下,系统会进行隐式转换的。当在程序中发现两个数据类型不相容时,又不能自动完成隐式转换,则将出现编译错误。例如:
   int* p = 100;
在这种情况下,编译程序将报错,为了消除错误,可以进行如下所示的强制类型转换:
   int* p = (int *)100; 
将整型数100显式地转换成指针类型。

构造函数具有类型转换功能

在实际应用中,当类定义中提供了单个参数的构造函数时,该类便提供了一种将其他数据类型的数值或变量转换为用户所定义数据类型的方法。因此,可以说单个参数的构造函数提供了数据转换的功能。下面通过一个例子进一步说明单参数构造函数的类型转换功能。

代码如下:

class A 
{
public:A(){ m=0; } A(doublei) { m=i; } void print() { cout<<M<<endl}
private:double m; 
};void main() 
{A a(5); a=10; //a与10是不同的数据类型a.print();
}



程序的输出结果为:
  10
在该程序中,赋值语句a=10;中,赋值号两边数值10和对象a是两上不相容的数据类型,可是它却能顺利通过编译程序,并且输出显示正确结果,其主要原因是得益于单参数的构造函数。编译系统选通过标准数据类型转换,将整型数值10转换成double型,然后,再通过类中定义的单参数构造函数将double型数值转换为A类类型,最后把它赋值给a。这些转换都是自动隐式完成的。

关于上面的程序,补充一点:
Aa = 10; 

Aa; 
a= 10; 
两者是不同的,前者对a进行初使化,编译器会尝试将10隐式转换为A类型,这样将引起a的A(doublei)构造函数直接被调用。
后者属于赋值语句,编译器将建立一个临时对象,并将10隐式转换为A类型。如果我们显示调用
(A)10;
这也将建立一个临时对象,引起A的构造函数被调用。

还有一点要注意,编译器只会进行一次隐式转换(C时刻库的内置类型如intshort char等)除外,下面的语句说明了这点:
m_rst->GetFields()->GetItem(nCol)->Value= (_bstr_t)sValue; 
上面Value是COM的变体类型,“Value=”将引起operator= (_bstr_t)被调用。如果上面省略(_bstr_t),编译器将发生错误,因为没有operator= (char*)这样的重载,编译器不会为我们进行两次以上的隐式转换。

在函数调用过程中,运算符重载和构造也是一个函数调用,如果匹配的函数如无二义性,那么将可以产生一次隐式转换。如果上句的Value变体类只有一个operate= (_bstr_t),那么既使这样写->Value= sValue; 编译器也会试图将sValue隐式转换为_bstr_t类型。

还有一种情况

代码如下:


classA 
{
    int a; 
public:
    A(){ }; 
    A(int_a) { a = _a; }; 
    Operator int() { return a; } 
}


有如下调用:

代码如下:


A a(10); 
A a2 = (int)(int)a;   //只相当于Aa2 = (int)a; 因为第一个就近已经转成了int,第二//个就不用再转了


比较有意思吧,A类既有将int隐式转换A的构造,也有int()转换函数供强制转换,(int)(int)a将以就近原则的方式进行。如果就近转换失败,编译器将报错。比如:

代码如下:


classB 
{
};
A a2 = (B)a; 

A a2 = (B)10; 


编译器报这样的错误:"errorC2440: “类型转换”:无法从“int”转换为“B”"
可知,我们自己编写的构造和转换函数多么重要。

转换函数
转换函数又称类型强制转换成员函数,它是类中的一个非静态成员函数。它的定义格式如下:

代码如下:


   class<类型说明符1>
    {
     public:
      operator<类型说明符2>();
      …
    }


这个转换函数定义了由<类型说明符1>到<类型说明符2>之间的映射关系。可见,转换函数是用来将一种类型的数据转换成为另一种类型。下面通过一个例子说明转换函数的功能。

代码如下:

 

#includeclass Rational 
{
public:Rational(intd, int n) {den= d; num= n; }operator double();//类型转换函数
private:int den, num; 
};Rational::operator double() 
{return double(den)/double(num); 
}void main() 
{Rational r(5, 8); double d = 4.7; d += r;  //这句将调用隐式转换,相当于d= (double)r; cout<<d<<ENDL;
}

程序输出结果:
5.325

 

由程序可知,d是一个double型数值,r是Rational类的对象,这两个不同类型的数据进行加法之所以能够进行是得益于转换函数operatordouble()。为使上述加法能够进行,编译系统先检查类Rational的说明,看是否存在在下转换函数能够将Rational类型的操作数转换为double类型的操作数。由于Rational类中说明了转换函数operatordouble(),它可以在程序运行时进行上述类型转换,因此,该程序中实现了d=r;的操作。

定义转换函数时应注意如下几点:
(1)转换函数是用户定义的成员函数,但它要是非静态的。
(2)转换函数的不可以有返回值。(意思是声明中不可以有返回值)
(3)转换函数也不带任何参数。
(4)转换函数函数还不能定义为友元函数。

转换函数的名称是类型转换的目标类型,因此,不必再为它指定返回值类型;转换函数是被用于本类型的数值或变量转换为其他的类型,也不必带参数。

类中的构造函数完成其他类型到类类型的转换,而重载强制转换完成类类型到其他类型的转换。

 

1.  operator 用于类型转换函数:

类型转换函数的特征:

1)  型转换函数定义在源类中;
2)  须由 operator 修饰,函数名称是目标类型名或目标类名;
3)  函数没有参数,没有返回值,但是有return
语句,在return语句中返回目标类型数据或调用目标类的构造函数。

类型转换函数主要有两类:

1)  对象向基本数据类型转换:

对象向不同类的对象的转换:

例程1:

//通过类型转换函数求半径为5的圆的面积
//并将其存储在float型变量中打印输出
#include <iostream>
using namespace std;
class CArea
{float area;
public:CArea(){area=0;}CArea(float a)           //重载含有一个参数的构造函数{area=a;}void getArea(){cout<<area<<endl;}void setArea(float a){area=a;}operator float()            //类型转换函数{                              //将面积类对象转换为float型数据return area;}
};
class CCircle
{float R;
public:void getR(){cout<<R<<endl;}void setR(float r){R=r;}operator CArea()   //类型转换函数{                                 //将圆类对象转为面积类对象float area=3.1415926*R*R;return (CArea(area));}   
};
void main()
{CCircle cir;CArea are;float a;cir.setR(5);cir.getR();                     //打印圆的半径are.getArea();           //打印转换前的面积                  are=cir;                 //将圆类对象转为面积类对象are.getArea();           //打印转换后的面积   a=are;                          //将面积类对象转换为float型数据cout<<a<<endl;                   
}	//将面积类对象转换为float型数据return area;}
};
class CCircle
{float R;
public:void getR(){cout<<R<<endl;}void setR(float r){R=r;}operator CArea()   //类型转换函数{                                 //将圆类对象转为面积类对象float area=3.1415926*R*R;return (CArea(area));}   
};
void main()
{CCircle cir;CArea are;float a;cir.setR(5);cir.getR();                     //打印圆的半径are.getArea();           //打印转换前的面积                  are=cir;                 //将圆类对象转为面积类对象are.getArea();           //打印转换后的面积   a=are;                          //将面积类对象转换为float型数据cout<<a<<endl;                   
}

 

 


2.  operator 用于操作符重载:


操作符重载的概念:

    
  将现有操作符与一个成员函数相关联,并将该操作符与其成员对象(操作数)一起使用。

注意事项:

1)  重载不能改变操作符的基本功能,以及该操作符的优先级顺序。

2)  重载不应改变操作符的本来含义。

3)  只能对已有的操作符进行重载,而不能重载新符号。

4)  操作符重载只对类可用。

5)  以下运算符不能被重载:

.       原点操作符(成员访问符)

*     指向成员的指针

::       作用域解析符

? :     问号条件运算符

sizeof 操作数的字节数

   操作符函数的一般格式:

               return_type operator op(argument list);

      return_type:返回类型(要得到什么)

        op:要重载的操作符

      argument list:参数列表(操作数有哪些)

例程2:

//重载大于号操作符比较两个人的工资
#include <iostream>
using namespace std;
class employee
{int salary;
public:void setSalary(int s){salary=s;}void getSalary(){cout<<salary<<endl;}bool operator >(const employee & e)//重载大于号操作符{if(salary > e.salary)return true;elsereturn false;}
};
void main()
{employee emp1,emp2;emp1.setSalary(1000);emp2.setSalary(2000);if (emp1 > emp2){cout<<"emp1比emp2工资高"<<endl;}else{cout<<"emlp1没有emp2工资高"<<endl;}
}

 

 

声明:operator XX(); 无返回值,XX就是某个类型;

用法:XX a = (XX)obj; 假设上边SocketAddress非abstract类,例如:SocketAddress sa; int a = (socklen_t)sa; 也就是此时会调用原成员函数operator XX(); 一般返回XX类型值,可以理解成类型转换的重载!

另外:一个自定义类的 构造函数可以用作隐形的类型转换,

例如:Class A { A(int i) { val = i};  private int val;} , A a = 5; 

解:5 首先通过构造函数A(int)隐形的转换为A类型,然后调用默认的operator=赋值函数,赋值给a;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018年世界科技发展回顾

来源&#xff1a;科技日报摘要&#xff1a;本文从科技政策、基础研究、信息技术、人工智能与先进制造、空间技术、能源环保等六个领域&#xff0c;回顾了2018年世界主要国家的科技发展。2019年或许会很不平常&#xff0c;只因2018年世界主要国家之间关系风云变幻&#xff0c;让…

给destoon商城的列表中和首页添加购物车功能

如何给destoon商城的列表中和首页添加购物车功能&#xff1f; 目前加入购物车的功能只存在商城的详细页面里&#xff0c;有时候我们需要批量购买的时候&#xff0c;希望在列表页就能够使用这个加入购物车的功能。 修改步骤见下&#xff1a; 例如在商城频道的首页和列表页加这个…

leetcode N-Queens

转载自&#xff1a;http://www.cnblogs.com/TenosDoIt/p/3801621.html N-Queens The n -queens puzzle is the problem of placing n queens on an n n chessboard such that no two queens attack each other. Given an integer n , return all distinct solutions to the …

javascript一些底层方法总结及用法

本地对象&#xff1a;ECMA-262 把本地对象&#xff08;native object&#xff09;定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。简单来说&#xff0c;本地对象就是 ECMA-262 定义的类&#xff08;引用类型&#xff09;内置对象&#xff1a;ECMA-262 把内置对象&…

CES新观察:智能应用全面开花 “陆海空”新品值得关注

来源&#xff1a;网易科技2019年国际消费性电子展&#xff08;以下简称“CES展”&#xff09;即将在美国拉斯维加斯落下帷幕&#xff0c;今年是CES走过的第52个年头&#xff0c;虽然已过了“知天命”的年纪&#xff0c;但这丝毫没有影响其在科技行业的影响力和创新力&#xff0…

BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草

1606: [Usaco2008 Dec]Hay For Sale 购买干草 Description 约翰遭受了重大的损失&#xff1a;蟑螂吃掉了他所有的干草&#xff0c;留下一群饥饿的牛&#xff0e;他乘着容量为C(1≤C≤50000)个单位的马车&#xff0c;去顿因家买一些干草&#xff0e; 顿因有H(1≤H≤5000)包干草…

BCG、阿里、百度联合发布中国互联网经济白皮书2.0,解读“中国互联网新篇章:迈向产业融合”...

来源&#xff1a;阿里研究院2017年9月13日&#xff0c;BCG携手阿里研究院、百度发展研究中心和滴滴政策研究院共同发布了中国互联网经济白皮书1.0&#xff0c;第一次全面解读了中国互联网的“中国特色”。该报告一经发布就在业界备受关注&#xff0c;仅在微信公众号上就吸引了超…

用户代码未处理EntityCommandExecutionmException报错解决方案

原因可能是&#xff08;1&#xff09;没有编译好&#xff0c;清理解决方案&#xff0c;重新生成解决方案。 &#xff08;2&#xff09;可能是WebSiteConfiguration.DbProviderName;中为DbProviderName属性赋值的时候可能从配置文件读设置&#xff0c;但是配置配置文件…

深度学习已经触底?这篇文章的观点令人信服吗?

来源&#xff1a;机器之心摘要&#xff1a;AI 迎来另一寒冬&#xff1f;这是 2018 年下半年至今我们一直能听到的一种声音。这类唱衰的文章一经发布&#xff0c;总是能博人眼球。这篇发表在 Medium 上的文章探讨了 AI 的历史和现在&#xff0c;泛谈了深度学习的局限性&#xff…

Leetcode unique-paths

转载自&#xff1a;http://blog.csdn.net/linhuanmars/article/details/22126357 原题链接: http://oj.leetcode.com/problems/unique-paths/ 这道题是比较典型的动态规划的题目。模型简单&#xff0c;但是可以考核动态规划的思想。我们先说说brute force的解法&#xff0c;…

阿里商业操作系统重磅发布!新零售绝对不止是零售层面的问题

来源&#xff1a;物联网智库摘要&#xff1a;2019年1月11日&#xff0c;阿里巴巴one商业大会在杭州隆重召开&#xff0c;阿里巴巴CEO张勇发表了题为《阿里巴巴商业操作系统》的主题演讲&#xff0c;并将此次大会称为“数字经济时代的网商大会”。会上&#xff0c;张勇宣布——在…

PHP操作MongoDB GridFS 存储文件

PHP操作MongoDB GridFS 存储文件&#xff0c;如图片文件 我的测试代码&#xff1a; 1、前端上传文件html index.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">…

JS入门程序(一)

程序代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><title>Bootstrap 101 Template</title><link href"css/bootstrap.min.css" rel"stylesheet" media"screen"></head><…

Oracle运行set autotrace on报错SP2-0618、SP2-0611

SQL> set autotrace on SP2-0618: 无法找到会话标识符。启用检查 PLUSTRACE 角色 SP2-0611: 启用 STATISTICS 报告时出错 原因: PLUSTRACE角色不存在 解决办法&#xff1a; conn / as sysdba %ORACLE_HOME%\sqlplus\admin\plustrce.sql grant plustrace to hr; 转载于:https…

万字长文回顾智能驾驶进化史

来源&#xff1a;软件定义世界&#xff08;SDX&#xff09;作者&#xff1a;吴甘沙、张玉新摘要&#xff1a;当卡尔 本茨发明汽车&#xff0c;人类进入汽车时代时&#xff0c;科学技术就对人类的 “ 出行 ” 进行了新的定义&#xff0c;而随着技术的不断发展与进步&#xff0c…

组合数学基本工具-- 排列与组合以及简单公式

排列 从n个不同元素中任取m&#xff08;m≤n&#xff09;个元素&#xff0c;按照一定的顺序排列起来&#xff0c;叫做从n个不同元素中取出m个元素的一个排列。当mn时所有的排列情况叫全排列。 P(n,m)n(n-1)...(n-m1)n!/(n-m)! 特别的&#xff0c;定义0!1 组合 组合公式是指从…

atitit.动态加载数据库配置in orm hibernate mybatis

atitit.动态加载数据库配置in orm 1. 动态加载数据库配置的优点::: 1 1.1. 组合多个配置文件... 1 1.2. 连接多个数据库 1 2. 基本的流程:::getCfg内存对象,,,,生成工厂类,在opoenSession 1 2.1. Hibernate动态添加配置流程 1 2.2. mybatis动态添加配置流程 1 2.3. #hb code 2 …

重磅!德勤TMT行业2019十大预测,遍地黄金的中国机会

来源&#xff1a;智东西摘要&#xff1a;着眼于全球科技、传媒和电信行业在未来5年的关键趋势&#xff0c;分析颠覆性技术变革及未来可能会影响行业内企业的因素。全球最大的会计事务所德勤于近日发布了《2019科技、传媒和电信行业预测》报告&#xff0c;该报告着眼于全球科技、…

组合数学-- 放回取样基础公式证明

放回取样 用CR(m , r) 表示放回取样或者重复取样时一个m集合的r组合的数量&#xff0c;例如在允许放回取样的情况下&#xff0c;集合{a , b}的4个元素的组合可以得到下面的结果&#xff1a; {a,a,a,a}, {b,b,b,b}, {a,a,a,b}, {a,a,b,b}, {a,b,b,b} 下面我们给出可放回取样…

PHP环境安全性能检查

PHP环境安全性能检查 PHP在Linux环境下安全配置是一个复杂的过程&#xff0c;其中涉及到很多的细节设置&#xff0c;在这里发出来一个脚本&#xff0c;通过这个脚本来检测你的PHP环境是否存在安全隐患&#xff0c;从而针对这些对你的PHP环境进行加固。功能&#xff1a; 1.检测P…