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. WCF NetTcpBinding

    服务端: <system.serviceModel> <bindings> <netTcpBinding> <binding portSharingEnabl ...

  2. python 爬虫 user-agent 生成

    有些网站做了反爬技术,如:比较初级的通过判断请求头部中的user-agent字段来检测是否通过浏览器访问的. 在爬这类网站时需要模拟user-agent import random import re ...

  3. mySql入门-(二)

    最近刚刚开始学习Mysql,然而学习MySql必经的一个过程就是SQL语句,只有按照文档从头开始学习SQL语句.学习的过程是痛苦的,但是学完的成果是甘甜的. SQL 语法 所有的 SQL 语句都以下列 ...

  4. vue项目在ie中空白问题

    vue项目在ie浏览器中出现空白,f12打开后发现在body下面就只有一个div盒子,因此我们可以猜测就是js没有引入导致的,所有网上看了一些相关的才知道,在ie中无法解析es6或者版本更高的语法,所 ...

  5. Centos6.10编译安装php-7.1.12并安装redis模块

    1.服务器初始化 yum update -yyum install epel-release -yyum install gcc gcc-c++ wget lsof lrzsz telnet -y 2 ...

  6. UCOSIII消息队列

    任务间消息传递2种途径 全局变量 发布消息 主结构体 typedef struct os_q OS_Q; struct os_q { /* Message Queue */ OS_OBJ_TYPE T ...

  7. linux设备模型与内核中的面向对象思想

    linux内核用C语言实现了C++面向对象的大部分特性:封装,继承,多态.在看内核的过程中,开始追寻其中的设计思想,封装.继承.多态.恰好今天又在看Linux设备模型,找了很多资料.总结如下: 1.l ...

  8. el-pagination分页优化

    表格分页优化: <template> <el-pagination small background @size-change="handleSizeChange" ...

  9. [LeetCode] 581. 最短无序连续子数组 ☆

    描述 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, 6, 4, 8 ...

  10. 关于C++模板不能分离编译的问题思考

    C++模板不支持分离编译的思考 前言 在我初入程序员这行时,因为学生阶段只写一些简单的考试题,所以经常是将声明和实现统一写到一个文件中,导致同事在用我的代码时一脸懵逼,因此还有一段悲惨的往事. 为什么 ...