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. Disruptor与Netty实现百万级(十)

    实体对象: import java.io.Serializable; public class TranslatorData implements Serializable { private sta ...

  2. 爬虫 HttpHelper

    /// <summary> /// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理 /// 重要提 ...

  3. .net core使用ocelot---第八篇 Consul

    简介 .net core使用ocelot---第一篇 简单使用   .net core使用ocelot---第二篇 身份验证使用  .net core使用ocelot---第三篇 日志记录  .net ...

  4. Mybatis中三种关联关系的实现

    目录 一对一查询 一对多查询 自关联查询: 多对多查询 总结: 三种关联关系:一对多,一对一,多对多 两种查询方式:嵌套查询,连接查询(也可称作:多表单独查询,多表连接查询) 每一种关联关系都可以通过 ...

  5. python3基础之“小练习(2)”

    (十三)创建一个你最喜欢歌手的列表. # singer=list() # singer=['a','b','c'] # print(singer) (十四)创建一个由元组构成的列表,每个元组包含居住过 ...

  6. 1、uiautomator2常用语法

    uiautomator2常用语法 连接设备 使用USB连接: d=u2.connect_USB('148b4090')输入手机序列号 d是给当前连接设备定位一个变量 获取设备的信息: print(d. ...

  7. 7. Input and Output

    7. Input and Output There are several ways to present the output of a program; data can be printed i ...

  8. 资源管理与调度系统-YARN的资源调度器

    资源管理与调度系统-YARN的资源调度器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 资源调度器是Hadoop YARN中最核心的组件之一,它是ResourceManager中的 ...

  9. Java获取各种路径

    (1).request.getRealPath("/");//不推荐使用获取工程的根路径(2).request.getRealPath(request.getRequestURI( ...

  10. Python 中 plt 画柱状图和折线图

    1. 背景 Python在一些数据可视化的过程中需要使用 plt 函数画柱状图和折线图. 2. 导入 import matplotlib.pyplot as plt 3. 柱状图 array= np. ...