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/archive/2012/07/07/2580800.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/54596

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午5:46
下一篇 2023年2月9日 上午5:47

相关推荐