C++ 运算符重载

1、 operator =
const Array& operator = ( const Array& rhs);
返回值不为void是考虑到需要支持a=b=c;这种情况
前面的const是考虑到(a=b)=c;这种情况时,应该报错

由编译器自动创建的函数包括:默认的构造函数、拷贝构造函数、operator = 、析构函数

2、 operator <<
operator >> 必须写成友元函数
原因是<<运算符的函数签名是 ostream& operator<<(ostream&, your_class&) 这里第一个参数是ostream类型,你不可能修改ostream类型的定义,因此你不可
能将它定义成ostream类的成员函数。你必须把它定义成一个普通的函数,如果这个函数需要拿到your_class的私有成员,那么你就把这个函数在your_class内部声
明为friend

    friend ostream& operator<<(ostream& outStream,const Rational& rhs);
    friend istream& operator>>(istream& inStream,Rational& rhs);

输入函数最后的参数不能为const;

3、必须重载为成员函数的运算符: [], (), –>, =
原因是这些运算符左边必须是这个类的变量(或者是子类的)。

4 自动类型转换
4.1 自动类型转换-构造函数转换

    class One
    {
    public:
        One(){}
    };

    class Two
    {
    public:
        Two(const One&){}   // here!
    };

    void f(Two){}

    int main()
    {
        One one;
        f(one);
    }

为避免构造函数自动转换可能引起的问题,可以在前面加 explicit 关键字

    class One
    {
    public:
        One(){}
    };

    class Two
    {
    public:
        explicit Two(const One&){}
    };

    void f(Two){}

    int main()
    {
        One one;
        // ! f(one); //不行了
        f(Two(one));
    }

4.2 自动类型转换-运算符转换

    class Three
    {
        int i;
    public:
        Three(int ii=0,int=0): i(ii){}
    };

    class Four
    {
        int x;
    public:
        Four(int xx): x(xx){}
        operator Three() const { return Three(x); } // here!
    };
    void g(Three) {}

    int main()
    {
        Four four(1);
        g(four);
        g(1);    // CALL Three(1,0);
    }

注意:使用构造函数技术没有办法实现从用户定义类型向内置类型转换,这只有运算符重载可能做到
4.3 自动类型转换的缺陷
4.3.1

    class Orange;

    class Apple
    {
    public:
        operator Orange() const;
    };

    class Orange
    {
    public:
        Orange(Apple);
    };

    void f(Orange);

    int main()
    {
        Apple a;
        f(a);
    }

当两种类型的转换同时存在时,编译器不知道应该执行哪一个
4.3.

    class Orange{};
    class Pear{};

    class Apple
    {
        operator Orange() const;
        operator Pear() const;
    };

    void eat(Orange);
    void eat(Pear);
    int main()
    {
        Apple c;
        eat(c);    // Error: Apple->Orange or Apple->Pear???
    }

当类中有多个向其他类型的转换时,它们不应该是自动转换,而应该是用如makeA()和makeB()这样的名字来创建显式的函数调用

5、 operator() 实现回调,下面是CEGUI中实现时间回调的一个雏形:

    class EventArgs
    {
    public:
        // construction
        EventArgs(): d_handled(false),d_hasWindow(false):{}
        // data members
        bool d_handled;
        bool d_hasWindow;
    };

    class FuctionSlotBase
    {
        virtual ~FuctionSlotBase(){}
        virtual operator()(const EventArgs& args) = 0;
    };

    template<typename T>
    class MemberFunctionSlot: public FuctionSlotBase
    {
    public:
        typedef bool(T::*MemberFunctionType)(const EventArgs&);

        MemberFunctionSlot(MemberFunctionType func, T* obj):
            d_function(func),
            d_object(obj)
        {}

        virtual bool operator(const EventArgs& args)
        {
            return (d_object->*d_function)(args);
        }

    private:
        MemberFunctionSlot d_function;
        T* d_object;
    };
原文地址:https://www.cnblogs.com/luleigreat/p/2580800.html