Aq系列C++——运算符重载 2.0

2020-10-25  本文已影响0人  StevenHD

博客示例源代码

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

class Complex 
{
public:
    Complex(int x, int y) : _x(x), _y(y) {}
    
    void dis() 
    {
        cout << "(" << _x << "," << _y << ")" << endl;
    }

#if 0

    const Complex& operator++(void) 
    {  
        // 前++
        _x++;
        _y++;
        
        return *this;
    }

    const Complex operator++(float) 
    {  
        // 后++引入哑元
        Complex t = *this;
        
        this->_x++;
        this->_y++;
    
        return t;
    }

#endif

    friend Complex& operator++(Complex& a);  // 前++
    friend const Complex operator++(Complex& a, int);  // 后++
    
private:

    int _x;
    int _y;
};

Complex& operator++(Complex& a) 
{  
    // 友元函数必须传引用
    a._x++;
    a._y++;

    return a;
}

const Complex operator++(Complex& a, int) 
{
    Complex c = a;
    
    a._x++;
    a._y++;

    return c;
}

int main()
{
    int x;
    //x ++++;
    cout << "------------" << endl;
    ++++ x;
    
    Complex a1(3, 4);
    Complex a2(3, 4);

    Complex c1 = ++++ a1;
    a1.dis();
    c1.dis();

    Complex c2 = a2 ++;
    a2.dis();
    c2.dis();

    return 0;
}

一定要注意,i ++++ i的区别,这里可以试一下i ++++++++ i,我们可以得到i ++++是不对的,原因是——

我们在实现后 ++ 的函数的时候,返回值的类型是const,这样子导致i ++后已经是一个const对象,如果再对这个const对象进行++操作,就会CE。我们通常使用引用&是为了节省空间,不会再更多地申请新的内存空间(如果是return by value就会比较浪费空间,因为我们已经可以保证它是const不变的了)。

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

class Complex 
{
public:
    Complex(int x, int y) : _x(x), _y(y) {}
    
    void dis() 
    {
        cout << "(" << _x << "," << _y << ")" << endl;
    }
    
#if 0

    Complex& operator++(void) 
    {  
        // 前++
        _x++;
        _y++;
        return *this;
    }

    const Complex operator++(int) 
    {  
        // 后++引入哑元
        Complex t = *this;
         
        this->_x++;
        this->_y++;
    
        return t;
    }

    friend Complex& operator++(Complex& a);             // 前++
    friend const Complex operator++(Complex& a, int);   // 后++
    
#endif

    friend ostream& operator<<(ostream& os, const Complex& c);
    friend istream& operator>>(istream& is, Complex& c);
    
private:

    int _x;
    int _y;
};

ostream& operator<<(ostream& os, const Complex& c)
{
    os << "(" << c._x << ", " << c._y << ")" << endl;
    return os;
}

istream& operator>>(istream& is, Complex& c)
{
    is >> c._x >> c._y;
    return is;
}

int main()
{
    Complex a1(3, 4);
    Complex a2(3, 4);

    cout << a1 << endl;
    
    cin >> a2;
    cout << a2 << endl;
    
    
    return 0;
}

流操作符只能用友元实现,不能用类成员函数,因为iostream是库函数。

#include <iostream>
#include <string>

using namespace std;

//Sender sender; Mail mail;
//sender << mail; Sender的类成员函数, Mail的友元

class Mail;
class Sender 
{
public:
    Sender(string s) : _addr(s) {}
    Sender& operator<<(const Mail& maill);      // 成员 
    
    // friend Sender& operator<<(Sender& sender, Mail& maill);
    
private:
    string _addr;
};

class Mail 
{
public:
    Mail(string title, string content) :_title(title), _content(content) {}
    
    // friend Sender& operator<<(Sender& sender, Mail& maill);
    
    friend Sender& Sender::operator<<(const Mail & mail);
    
private:
    string _title;
    string _content;
};

Sender& Sender::operator<<(const Mail & mail)
{
    cout << "Address:" << _addr << endl;
    cout << "Title :" << mail._title << endl;
    cout << "Content:" << mail._content << endl;
    
    return *this;
}

// #if 0

// 方式2
// Sender& operator<<(Sender& sender, Mail& mail) 
// {
//     cout << "Address:" << sender._addr << endl;
//     cout << "Title :" << mail._title << endl;
//     cout << "Content:" << mail._content << endl;
    
//     return sender;
// }

// #endif

int main() 
{
    Sender sender("11111@163.com");
    
    Mail mail("note", "meeting at 3:00 pm");
    Mail mail2("tour", "One night in beijing");
    
    sender << mail << mail2;
    
    return 0;
}

这个相当于是上面流操作符重载的说明


#include <iostream>
#include <string>

using namespace std;

class Point3D;

class Point2D 
{
public:

    Point2D(int x, int y) :_x(x), _y(y) {}

    void dis()
    {
        cout << "(" << _x << "," << _y << ")" << endl;
    }

    friend Point3D; // 友元类, 可以访问Point2D的私有成员变量
    
private:

    int _x;
    int _y;
};

class Point3D
{
public:

    Point3D(int x, int y, int z) : _x(x), _y(y), _z(z) {}
    
    explicit Point3D(Point2D &p)
    {
        cout << "调用构造函数" << endl;
        
        this->_x = p._x;
        this->_y = p._y;
        this->_z = 0;
    }
    
    void dis()
    {
        cout << "(" << _x << "," << _y << "," << _z << ")" << endl;
    }
    
private:

    int _x;
    int _y;
    int _z;
};


int main() 
{
    Point2D p2(1, 2);
    p2.dis();

    Point3D p3(3, 4, 5);
    p3.dis();


    Point3D p3a = p2;   //使用explicit后不会隐式的进行类型转换;
    
    // Point3D p3a = Point3D(p2);  // 一个显式的转换
    p3a.dis();

    return 0;
}

这里就是学了下explicit

#include <iostream>
#include <string>

using namespace std;

class Point3D;

class Point2D 
{
public:
    Point2D(int x, int y) :_x(x), _y(y) {}

    void dis()
    {
        cout << "(" << _x << "," << _y << ")" << endl;
    }

    operator Point3D();

    friend Point3D; // 友元类, 可以访问Point2D的私有成员变量
    
private:
    int _x;
    int _y;
};

class Point3D
{
public:
    Point3D(int x, int y, int z) : _x(x), _y(y), _z(z) {}

// #if 0

//     explicit Point3D(Point2D &p)
//     {
//         cout << "调用构造函数" << endl;
        
//         this->_x = p._x;
//         this->_y = p._y;
//         this->_z = 0;
//     }
    
// #endif
    
    void dis()
    {
        cout << "(" << _x << "," << _y << "," << _z << ")" << endl;
    }
    
private:

    int _x;
    int _y;
    int _z;
};

Point2D::operator Point3D() 
{
    return Point3D(_x, _y, 123);
}

int main() 
{
    Point2D p2(1, 2);
    p2.dis();

    Point3D p3(3, 4, 5);
    p3.dis();


    // Point3D p3a = p2;   //使用explicit后不会隐式的进行类型转换;
    Point3D p3a = p2;  //一个显式的转换
    p3a.dis();

    return 0;
}

这里没有用explicit,而是重载了一下operator函数。

上一篇下一篇

猜你喜欢

热点阅读