C++中利用构造函数与无名对象简化运算符重载函数

  在完整描述思想之前,我们先看一下如下的例子,这个例子中的加运算符重载是以非成员函数的方式出现的:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream> 
using namespace std; 
 
class Test   
{   
    public:   
        Test(int a) 

        { 
            Test::a = a; 

        } 
        friend Test operator + (Test&,int); 
    public: 

        int a; 
}; 
Test operator + (Test &temp1,int temp2) 

    Test result(temp1.a + temp2); 
    return result; 


int main() 


    Test a(100); 
    a = a + 10;//正确 
    a = 10 + a;//错误 

    cout<<a.a<<endl; 

    system("pause"); 
}

上面的代码是一个自定义类对象与内置整型对象相加的例子,但错误行让我们猛然感觉很诧异,但仔细看看的确也在情理中,参数顺序改变后c++无法识别可供使用的运算符重载函数了。

  我们为了适应顺序问题不得不多加一个几乎一样的运算符重载函数。

  代码如下:

//程序作者:管宁 
//站点:www.cndev-lab.com 
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream> 
using namespace std; 
 
class Test   
{   
    public:   
        Test(int a) 

        { 
            Test::a = a; 

        } 
        friend Test operator + (Test&,int); 
        friend inline Test operator + (Test&,int); 
    public: 
        int a; 
}; 

Test operator + (Test &temp1,int temp2) 


    Test result(temp1.a + temp2); 
    return result; 

inline Test operator + (int temp1,Test &temp2)//利用内联函数的定义提高效率 

    return temp2+temp1; 

int main() 


    Test a(100); 
    a = a + 10;//正确 
    a = 10 + a;//正确 

    cout<<a.a<<endl; 

    system("pause"); 
}

  代码中我们使用内联函数的目的是为了缩减开销,但事实上我们仍然觉得是比较麻烦的,例子中的情况都还是非成员函数的情况,如果运算符重载函数是作为类成员函数,那么问题就来了,重载函数的第一个参数始终被隐藏,我们无发让int形参排列在隐藏参数的前面,从而导致a
= 10 + a;无法获取正确的运算符重载函数。

  有问题的代码如下:

class Test   
{   
    public:   
        Test(int a) 

        { 
            Test::a = a; 

        } 
        Test operator + (int temp2) 
        { 

                Test result(temp1.a + temp2); 

                return result; 
        } 

        Test operator + ()//第一个参数被隐藏,怎么办????,int形参无法放到this指针的前面,理想中的应该是(int temp1,Test *this) 

        { 
 
        } 
    public: 

        int a;   
};

  对于这个问题难道没有办法解决吗?
  答案是否定的,我们可以利用类构造函数对参与运算的整型对象进行显式的类型转换,从而生成无名对象参与同类型对象的加运算,这样做可以缩减代码量,提高程序的可读性。

  代码如下(例一为非成员形式,例二为成员形式):

//例一 
 
//程序作者:管宁       
//站点:www.cndev-lab.com       
//所有稿件均有版权,如要转载,请务必著名出处和作者    
 
#include <iostream> 
using namespace std; 
 
class Test   
{   
    public:   
        Test(int a)//事实上构造函数起的转换作用本质就是产生无名对象 

        { 
            Test::a = a; 

        } 
    friend Test operator + (Test&,Test&); 

    public: 
    int a; 

}; 
Test operator + (Test &temp1,Test &temp2) 


    Test result(temp1.a + temp2.a); 
    return result; 

int main() 

    Test a(100); 
    a = a + Test(10);//显式转换,产生无名对象 
    a = Test(10) + a; 
    cout<<a.a<<endl; 
    a = 50 + 1;//先进行50+1的内置整型的加运算,然后进行a=Test(51)的隐式转换 
    cout<<a.a<<endl; 
    system("pause"); 

}

//例二 
 
//程序作者:管宁       
//站点:www.cndev-lab.com       
//所有稿件均有版权,如要转载,请务必著名出处和作者 
 
#include <iostream> 
using namespace std; 
 
class Test   
{   
    public:   
        Test(int a)//事实上构造函数起的转换作用本质就是产生无名对象 

        { 
                Test::a = a; 

        } 
        Test operator + (Test &temp)//第一个参数即使隐藏也没有关系,因为是以Test类型的无名对象参与运算的 
        { 

                Test result(this->a + temp.a); 
                return result; 
        } 
    public: 
        int a; 
}; 

 
int main() 


    Test a(100); 
    a = a + Test(10); 
    a = Test(10) + a; 
    cout<<a.a<<endl; 
    a = 50 + 1;//先进行50+1的内置整型的加运算,然后进行a=Test(51)的隐式转换 
    cout<<a.a<<endl; 
    system("pause"); 

}

  认真观察了上面的两个例子后我们可以发现,类的构造函数起了显式或者隐式转换的作用,转换过程实质是产生一个类的无名对象,类的运算符重载函数的参数就是这个无名对象的引用,所以参数的顺序也不再是问题,代码的运行效率也得到提高,无需再定义只是参数顺序不同,内容重复的运算符重载函数了。

 
 

《挑战30天C++入门极限》C++中利用构造函数与无名对象简化运算符重载函数的更多相关文章

  1. 《挑战30天C++入门极限》C++运算符重载转换运算符

        C++运算符重载转换运算符 为什么需要转换运算符? 大家知道对于内置类型的数据我们可以通过强制转换符的使用来转换数据,例如(int)2.1f;自定义类也是类型,那么自定义类的对象在很多情况下也 ...

  2. 《挑战30天C++入门极限》C++的iostream标准库介绍(3)

        C++的iostream标准库介绍(3) C语言提供了格式化输入输出的方法,C++也同样,但是C++的控制符使用起来更为简单方便,在c++下有两中方法控制格式化输入输出. 1.有流对象的成员函 ...

  3. 《挑战30天C++入门极限》C++的iostream标准库介绍(1)

        C++的iostream标准库介绍(1) 我们从一开始就一直在利用C++的输入输出在做着各种练习,输入输出是由iostream库提供的,所以讨论此标准库是有必要的,它与C语言的stdio库不同 ...

  4. 《挑战30天C++入门极限》C++运算符重载赋值运算符

        C++运算符重载赋值运算符 自定义类的赋值运算符重载函数的作用与内置赋值运算符的作用类似,但是要要注意的是,它与拷贝构造函数与析构函数一样,要注意深拷贝浅拷贝的问题,在没有深拷贝浅拷贝的情况下 ...

  5. 《挑战30天C++入门极限》对C++递增(增量)运算符重载的思考

        对C++递增(增量)运算符重载的思考 在前面的章节中我们已经接触过递增运算符的重载,那时候我们并没有区分前递增与后递增的差别,在通常情况下我们是分别不出++a与a++的差别的,但的确他们直接是 ...

  6. 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态

        C++运算符重载函数基础及其值返回状态 运算符重载是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观. 对于普通对象来说我们很自然的会频繁使用算数运 ...

  7. 《挑战30天C++入门极限》新手入门:C++中堆内存(heap)的概念和操作方法

        新手入门:C++中堆内存(heap)的概念和操作方法 堆内存是什么呢? 我们知道在c/c++中定义的数组大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作 ...

  8. 《挑战30天C++入门极限》新手入门:C++中的函数重载

        新手入门:C++中的函数重载 函数重载是用来iostream>  using namespace std;  int test(int a,int b);  float test(flo ...

  9. 《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)

        新手入门:关于C++中的内联函数(inline) 在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数. 可能说到这里,很 ...

随机推荐

  1. 禁止迅雷极速版被强制升级为迅雷x

    PS:迅雷极速版( ThunderSpeed1.0.34.360 )下载地址: https://pan.baidu.com/s/1wuBOpNbim5jBru03AfSAVg 按照下面的这个路径去找. ...

  2. HTTP缓存字段总结

    首部 通用首部:有些首部提供了与报文相关的最基本的信息,它们被称为通用首部. 请求首部:请求首部是只在请求报文中有意义的首部. 响应首部 实体首部: 用来描述HTTP报文的负荷,由于请求和响应报文中都 ...

  3. 深入理解React 组件状态(State)

    React 的核心思想是组件化的思想,应用由组件搭建而成,而组件中最重要的概念是State(状态),State是一个组件的UI数据模型,是组件渲染时的数据依据. 一. 如何定义State 定义一个合适 ...

  4. 删除Ubuntu的UEFI启动项

    bcdedit 删除 千万不要手贱用diskpart之类的命令直接删除文件夹,大写的没,有,用! 感谢这个视频的up主,youtube看不到请翻墙.https://www.youtube.com/wa ...

  5. MYSQL5.7.24编译安装

    1.解压源代码包 #tar zxvf mysql-boost-8.0.17.tar.gz 2.安装依赖包 #yum -y install gcc gcc-c++ ncurses ncurses-dev ...

  6. 解决ifuse不支持24位UDID问题

    在使用ifuse对iphone设备进行沙盒挂载时, 对类似XXXXXXXX-XXXXXXXXXXXXXXXX UDID设备会提示Invalid device UDID specified, lengt ...

  7. LB_Keogh

    LB_Keogh LB_Keogh 是Keogh设计的下界函数,相比于LB_Kim以及LB_Yi具有更好的效果. 公式 注释: 上面公式中的 u 和 l 指的是上下包络线 对公式解释一下,其实就是,首 ...

  8. 关于Istio 1.1,你所不知道的细节

    本文整理自Istio社区成员Star在 Cloud Native Days China 2019 北京站的现场分享 第1则 主角 Istio Istio作为service mesh领域的明星项目,从2 ...

  9. 使用git clone 出现 Permission denied 解决办法

    从git复制项目到本地的一种方式是使用ssh方式,即在git bash中运行命令:git clone git@github.com:***.git 此种方式下载代码到本地的时候,可能出现Permiss ...

  10. 剑指Offer(三十三):丑数

    剑指Offer(三十三):丑数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_31 ...