美文网首页
Aq系列C++——运算符重载 2.0

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

作者: StevenHD | 来源:发表于2020-10-25 11:48 被阅读0次

    博客示例源代码

    • 重载前++和后++
    #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函数。

    相关文章

      网友评论

          本文标题:Aq系列C++——运算符重载 2.0

          本文链接:https://www.haomeiwen.com/subject/bntwmktx.html