随笔 - 25, 文章 - 0, 评论 - 6, 引用 - 0
数据加载中……

C++操作符重载

//原文链接: http://blog.csdn.net/xiegenwendada/article/details/8477209 

#include<stdio.h>  
#include <stdlib.h>  

/*///////////////////////////// 操作符重载 ////////////////////////////////////////////
-
-    操作符重载必须是,参数类型或个数不同,还有是否为const,但不以返回值的类型左判断。
-
-    ------------------------------------------------------------------------------------    
-    |            不能重载的操作符号            |            可以重载的操作符                |
-    ------------------------------------------------------------------------------------
-    |    . .* :: ?: new delete sizeof        |    new new[] delete delete[] + - * / % ^    |
-    |    typeid static_cast dynamic_cast        |    & | ~ ! = < > += -= *= /= %=  ^= &= |=    |
-    |    const_cast reintERPret_cast            |    << >> >>= <<= == != <= >= && || ++ --    |
-    |                                        |    ->* -> () []                            |
-    -------------------------------------------------------------------------------------
-    
-
-    ------------------------------------------------------------------------------------    
-    |            类成员操作符重载            |            友员函数操作符重载                |
-    ------------------------------------------------------------------------------------
-    |        左右操作数都是该类对象            |            左操作数为其它类型                |
-    | 必须为类成员操作符:                    |                                            |
-    | 赋值(=),下标([]),调用(())        |                                            |
-    | 和成员访问箭头(->)                    |                                            |
-    -------------------------------------------------------------------------------------
-
//////////////////////////////// 操作符重载 ////////////////////////////////////////////
*/

// 简单的重载
class CBaseOperator  
{  

public:  
    int nData;        //测试的变量  

public:  
    CBaseOperator(int nData = 0):nData(nData)  
    {  
        nData++;  
        --nData;  
    }  


    CBaseOperator(const CBaseOperator& cBO)  
    {  
        nData = cBO.nData;  
    }  
    //重载=操作符,一般=操作符和拷贝构造函数是成对出现的。  
    const CBaseOperator& operator=(const CBaseOperator& cBO)  
    {  
        nData = cBO.nData;  
        return *this;  
    }  

public:  

    //重载+操作符,简单的二元操作符重载是最常见也是比较简单的。基本思路都是这样,注意如果  
    
//操作符出现在左边,则只能用友员了。这里了有几个返回类型是CBaseOperator,return  
    
//语句中却是两个int相加,这种情况是可以通过的,编译器会自动构建一个相应的对象返回,  
    
//前提是你的构造函数要有相应的参数,这里是int作为参数  
    int operator+(int nAdd) const  
    {  
        return nData + nAdd;  
    }  

    int operator+(int nAdd)  
    {  
        return nData + nAdd;  
    }  

    friend int operator+(int nAdd,const CBaseOperator& cAdd)  
    {  
        return nAdd + cAdd.nData;  
    }  

    CBaseOperator operator+(const CBaseOperator& cAdd) const  
    {  
        return nData + cAdd.nData;  
    }  

    //重载减法什么的也是一样。就不写了。哈哈  

    
//比较操作符重载==,!=,>, >=, <, <=总结:这里都是配套的操作一般来说如果写一个  
    
//都会重载其他几个,特别是==,!=。当然也有例外。哈哈。。  
    bool operator==(const CBaseOperator& cEqual) const  
    {  
        return nData == cEqual.nData;  
    }  
    bool operator == (int nEqual) const  

    {        

        return nData == nEqual;  
    }  
    friend bool operator ==(int nEqual, const CBaseOperator& cEqual)  
    {  
        return cEqual.nData == nEqual;  
    }  
    bool operator!=(const CBaseOperator& cEqual) const  
    {  
        return nData != cEqual.nData;  
    }  

    //其他的也就不写了,基本一样。哈哈  

    
//重载++,--操作符,因为++,--有两种方式,一种是前增量(++XXX先改变自己,返回),  
    
//一种是后增量(改变自己,返回改变前的状态)  
    
//因为重载是判断参数的,为了能区别前增量和后增量,C++的设计者做了这样的考虑。  
    
//就是重载后增量的时候在参数列表中加一个int类型参数,这样就避免的重载的重复了。  
    
//在调用上,如果都重载,那么用int参数的是后增量++,没有参数的是前增量++,  
    
//(注:我在这里说的是成员函数,当然友员的重载参数个数要多一个,以后的我可别说我无知啊。)  
    
//如果都重载,那么前增量和后增量都会调用相应的函数,如果只重载了后增量,那么前增量会失败  
    
//如果只重载了前增量,就会无论是前增量和后增量都会调用这个函数。所以一般他们也是成对  
    
//出现的,除非你懒,只写前增量,可惜如果人家要调用后增量呢?结果会错的哦。哈哈。  

    
//重载后增量.  
    CBaseOperator operator++(int)  
    {  
        CBaseOperator cTemp = *this;  
        ++nData;  
        return cTemp;  
    }  

    //重载前增量  
    CBaseOperator& operator++()  
    {  
        ++nData;  
        return *this;  
    }  

    //重载--操作符是一样的,也不写了。  

    
//重载[],()等操作符号,同样[]的参数个数是确定的。  
    
//我之说以把他们写一起,是因为我错误的以为[]的参数个数是可以自己定义。错了错了。  
    
//知错能改是好的,对了,()的参数个数是可以自己定义的。这个就给我们很大的发挥空间了。  
    
//都忘了[],() = 等操作符必须是成员函数,上面有写。不能用友员和静态成员函数  

    
//重载[]  
    int operator[](int nIndex) const  
    {  
        return nIndex;  
    }  

    //重载()  
    int operator()(int a) const  
    {  
        return a;  
    }  

    bool operator()(int a, int b) const  
    {  
        return a > b;  
    }  

    CBaseOperator operator()(int a, int b, int c)  
    {  
        return CBaseOperator(a+b+c+*this);  
    }  

    //重载*,->的操作符,*操作符就是相当于指针的*p;不过这里已经失去了原来的意义,他不是一个指针了。  
    
//但如果是想通过他来得到一些东西,也是可以的,特别在迭代器中常用这种方法。->也是和*配对出现的。  
    
//不过->操作符比较有意思,貌似和(*p).dddd真的差不多,所以返回的应该是一个结构的指针,我们这里  
    
//就返回了本身,当然可以返回任何结构的指针的。(并不是只能返回本身)。  

    
//重载*,这里参数个数是固定的,多写一个就成了乘法的操作了。哈哈  
    int operator*() const  
    {  
        return nData;  
    }  

    //重载->  
    CBaseOperator* operator->()  
    {  
        return this;  
    }  

    //其他的例如&& || 这样的操作符还是不重载的好。利用其原有的本性  

    
//重载new delete,这里编译器做了一个限制,new必须返回void*类型, delete必须  
    
//返回void类型。(上面说过函数重载是不检查返回类型的,和这里并没有冲突,他只是限定了返回  
    
//类型,而不是只有返回类型不同的函数能重载,这个是编译器做的工作,一定上确保new能更好的工作吧)  
    
//还有就是他们的参数个数都是可以自定义的。new 和 new[] 是两个不同的操作符,所以还是要分别重载一下。  
    
//delete 和 delete[] 也是两个不同的操作符。这里只重载了一个。  
    voidoperator new(size_t size)  
    {  

        return  malloc(size);  
    }  

    voidoperator new[](size_t size)  
    {  
        return  malloc(size);  
    }  

    void operator delete(void* P, unsigned int size)  
    {  
        size = 0;  
        free(P);  
    }  
};  

int test_OverLoad()  
{  
    const CBaseOperator cCo1(100);  

    //判断+重载符  
    int nSum = cCo1 + 50;  
    printf("%d\n", nSum);  
    nSum = 50 + cCo1;  
    printf("%d\n", nSum);  

    //这里顺便检测一下拷贝构造函数  
    CBaseOperator co2(20);  
    CBaseOperator co3 = co2 + cCo1;  
    nSum = co3.nData;  
    printf("%d\n", nSum);  

    nSum = co3 + 60;  
    printf("%d\n", nSum);  

    //检测+,和=操作符  
    co3 = 10 + cCo1 + co2 + 20;  
    nSum = co3.nData;  
    printf("%d\n", nSum);  

    //查看比较操作符  
    if (cCo1 == cCo1 && cCo1 == 100 && 100 == cCo1)  
    {  
        printf("True\n");  
    }  
    co3 = co2;  
    if (!(co3 != co2))  
    {  
        printf("True\n");  
    }  

    //增量操作符,cCo1是不能做这个操作的,因为他是常量  
    nSum = co2.nData;  

    printf("%d\n", nSum);  

    nSum = (co2++).nData;  
    printf("%d\n", nSum);  
    nSum = (++co2).nData;  
    printf("%d\n", nSum);  

    //测试[],  
    nSum = cCo1[45];  
    printf("%d\n", nSum);  

    //测试()  
    nSum = cCo1(50);  
    printf("%d\n", nSum);  

    if (cCo1(45, 23))  
    {  
        printf("True\n");  
    }  

    co2 = co3(10,20,30);  
    nSum = co2.nData;  
    printf("%d\n", nSum);  

    //测试*,这里co2并不是指针哦。只是重载了*的操作符  
    nSum = *co2;  
    printf("%d\n", nSum);  

    //测试->,这里也一样。  
    nSum = co2->nData;  
    printf("%d\n", nSum);  

    //测试new new[] delete,  
    
//这里没有测试输出。单步就知道了。  
    CBaseOperator* pCb1 = new CBaseOperator();  
    CBaseOperator* pCb2 = new CBaseOperator[10];  
    delete pCb1;  
    delete pCb2;  
    system("pause");  
    return 0;  

posted on 2013-03-07 11:07 chenjt3533 阅读(178) 评论(0)  编辑 收藏 引用 所属分类: C/C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理