[类和对象]5 运算符重载

总结

操作符重载是C++的强大特性之一

操作符重载的本质是通过函数扩展操作符的语义

operator关键字是操作符重载的关键

friend关键字可以对函数或类开发访问权限

操作符重载遵循函数重载的规则

操作符重载可以直接使用类的成员函数实现

=, [], ()和->操作符只能通过成员函数进行重载

++操作符通过一个int参数进行前置与后置的区分和重载

C++中不要重载&&和||操作符

 

 

 

#include <iostream>
using namespace std;

class F
 {
public:
    int operator() (int a, int b) { // 重载()
        return a*a + b*b;
    }
};

class F2
 {
public:
    int MemFunc(int a, int b) {
        return a*a + b*b;
    }
};

class Complex
 {
public:
//构造
    Complex(int a=0, int b=0)
    {
        this->a = a;
        this->b = b;
    }

private: //友元
    friend Complex myAdd(Complex &c1, Complex &c2);
    //重载+运算符
    friend Complex operator+(Complex &c1, Complex &c2);
    //重载 前置++
    friend Complex& operator++(Complex &c1);
    friend Complex  operator++(Complex &c1, int);    
    //重载 <<
//     friend void operator<<(ostream &out, Complex &c1);
    friend ostream& operator<<(ostream &out, Complex &c1);
    
public://运算符重载    成员函数法
    Complex operator-(Complex &c2)
 {
 //实现 -运算符重载
        Complex tmp(this->a - c2.a, this->b - c2.b);
        return tmp;
    }

    Complex operator--()
 {
 //前置--
        this->a --;
        this->b --;
        return *this;
    }
    
    Complex operator--(int) //利用占位符和前置--区分
   {
//后置--
        Complex tmp = *this; //先使用  再-- 
        this->a--;
        this->b--;
        return tmp;
    }

public://普通函数
    void printCom()
 {
        cout<<a<<" + " << b << "i" <<endl;
    }
    
private:
    int a;
    int b;
    
};



//1 定义了全局函数
Complex myAdd(Complex &c1, Complex &c2)
{
    Complex tmp(c1.a + c2.a, c1.b+ c2.b);
    return tmp; 
}

//2 函数名 升级
//实现 + 运算符重载   全局函数法 
Complex operator+(Complex &c1, Complex &c2)
{
    cout<<"operator+"<<endl;
    Complex tmp(c1.a + c2.a, c1.b+ c2.b);
    return tmp; //
}

//前置++
Complex& operator++(Complex &c1)
{
    c1.a++;
    c1.b++;
    return c1;
}

//后置++
Complex operator++(Complex &c1, int) //利用占位符和前置++区分 
{
    //先使用 再让c1++ 
    Complex tmp = c1;
    c1.a ++;
    c1.b ++;
    return tmp;
}


// 重载 <<
// void operator<<(ostream &out, Complex &c1)
// {
//     out<<"<< 运算符重载"<<endl;
//     out<<c1.a << " + " << c1.b << "i" << endl;
// }

// 重载 <<
ostream& operator<<(ostream &out, Complex &c1)
{
    out<<"<< 运算符重载"<<endl;
    out<<c1.a << " + " << c1.b << "i" << endl;
    return out;
}





int main(void)
{    
/*==========================
 * dm01 运算符重载技术入门推演
 ==========================*/    
    cout << "dm01 运算符重载技术入门推演" << endl;
    int m = 1,  n= 2;
    int k;
    //1 基础数据类型 编译器已经知道了. 如何运算
    
    k = m + n;     

    // a + bi 复数运算规则
    Complex c1(1, 2), c2(3, 4);
    Complex c3; 
    //2 类 也是一种数据类型  用户自定义数据类型 C++编译器 是不知道如何进行运算
//    c3 = c1 + c2 ;
//    c1--; --c1

    //3 c++编译器应该给我们程序员提供一种机制 ... 
    //让自定义数据类型 有机会 进行 运算符操作 ====> 运算符重载机制 

    //4 运算符重载机制
    //步骤1     普通函数myAdd
//    Complex c4 = myAdd(c1, c2);
//    c4.printCom();

    //步骤2  operator+ 看作函数名myAdd
//    Complex c4 = operator+(c1, c2);
//    c4.printCom();

    //步骤3  +替换 函数名
//     Complex c3 = c1 + c2;
//     c3.printCom();

/*----------------------------------------------------------------------------------------------------------
 * 运算符重载的本质 是 函数调用 
 * 
 * 思考C++编译器如何支持操作符重载机制的 (根据类型) ?

    遇到 Complex c4 = c1 + c2; 时, IDE是不知道这里的 + 是怎么运算的 
    开始检测程序员是否对 + 和 这个类 进行了运算符重载[operator+]   
----------------------------------------------------------------------------------------------------------*/ 

/*==========================
 * dm02 运算符重载的两种方法
 *             全局函数法
 *             成员函数法
 ==========================*/

cout << "dm02 运算符重载的两种方法" << endl; cout << "+ - 前置++ 后置++ 前置-- 后置--" << endl; //1 全局函数法 实现 + 运算符重载 // Complex operator+(Complex &c1, Complex &c2); c3 = c1 + c2; c3.printCom(); // 2 成员函数法 实现 - 运算符重载 //c1.operator-(c2); // Complex operator-(Complex &c2) Complex c4 = c1 - c2; c4.printCom(); //前置++操作符 全局函数 ++c1; c1.printCom(); //前置--操作符 成员函数 --c1; c1.printCom(); //后置++操作符 全局函数 //Complex operator++(Complex &c1) c1++; c1.printCom(); //后置--操作符 成员函数 //c1.operator--() //Complex& operator--(); c1--; c1.printCom(); /*========================== * dm03 运算符重载 << ==========================*/ cout << "dm03 运算符重载 <<" << endl; cout<< k << endl;//常规 // 1 全局函数法 cout << c1; // 2 成员函数法 // 在ostream这个类里 添加 成员函数 operator<<() // cout.operator<<(c1); // 但是无法在预定义好的类里添加,所以只能用全局函数法 /* 拓展: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * 如果既要输出c1,同时又要输出常规的,该怎么做 例如: cout << c1 << "abcde"; 如果用 void operator<<(ostream &out, Complex &c1); 第一步: cout.operator<<(c1) 返回一个void 第二步: void.operator<<("abcde"); ∴报错了 综上:如果需要混合输出, 函数返回值当左值 需要返回一个引用 */ cout << c1 << "abcde";
/*========================== * dm04 运算符重载 = * 参考 深拷贝 浅拷贝 ==========================*/ cout << "dm04 运算符重载 =" << endl; // http://www.cnblogs.com/-Mr-y/p/7801892.html#_label3 /*========================== * dm05 运算符重载 () [] * 重载[]和()运算符 运算符 [] 和 () 是二元运算符 [] 和 () 只能用成员函数重载,不能用友元函数重载 ==========================*/ cout << "dm05 运算符重载 () []" << endl; F f; f(2, 4); // f.operator(2, 4); F2 f2; f2.MemFunc(2, 4); /*========================== * dm06 不要重载 && 和 || 操作符 ==========================*/ cout<<"hello..."<<endl; return 0; }

 

posted @ 2017-11-08 15:47  _Mr_y  阅读(304)  评论(0编辑  收藏  举报
levels of contents