• C++抽象机制之二:运算符重载


    1.二元运算符aa@bb,可以定义为

    1).一个参数的非静态成员函数:aa.operator@(bb);  (成员函数有this指针)

    2). 两个参数的非成员函数:operator@(aa,bb);

    一元运算符@aa,可以定义为

    1).无参数的非静态成员:aa.operator@();

    2).一个参数的非成员:operator@(aa).

    2.

    --operator=, operator[],operator(),operator-> 只能作为非静态成员函数;

    --一个运算符函数要么是成员,要么有一个参数为用户定义类型;

    --不存在运算符屏蔽的问题,保证了用户可以提供新的功能而不用去修改现有功能。

    --二元的operator@,x@y解析方式(顺序):类x的成员或者某个基类成员---->该环境中的operator申明----->x的名字空间---->y的名字空间

    3.+=比+ & =有效,前者没有采用临时变量;混合模式算术也是通过重载实现,基础是operator+=()

    4.

    --构造函数的作用:通过已有类型的值构造出程序所需的类型,如:complex(double r):re(r),im(0){}

    --默认的复制构造函数就是简单地复制成员,完成从用类对象取初始化同类对象;

    --复制构造函数不但被用在初始化变量是,还用在参数传递、值返回、以及异常处理中?

    --构造函数和转换:参数的不同组合很可能会造成组合爆炸问题,此时依赖于转换。有了complex(double r):re(r),im(0){}和bool operator==(complex,complex), 3==y<=>operator==(complex(3),y)

    --转换运算符:X::operator T() ,T是一个类型名,定义了一个从x到T的转换。

    (1)从用户定义类型到内部类型;(2)从新类型到已有类型,而不修改已有的类。如:INT::operator int()

    5.

    --成员函数:

    1).访问私有;

    2).位于类的作用域中;

    3).该函数必须由对象激活(this指针)

    1)2)->static;; 1)->friend

    --若要求某运算对象是基本类型的左值,将该运算符定义为成员函数最自然(= 、+=、++等等);一个修改类对象的操作要么定义为成员函数,要么定义为非const引用(指针)全局函数;相反,若希望某个运算符所有运算对象都能隐式转换,那些不需要基础类型左值的运算符,就应该作为非成员or取const引用从参数or非引用参数。
    需要访问对象内部的,(如reim)应该作为friend。因为对象内部数据一般是作为private。

    --友元函数,友元类。友元类的寻找:1)在外围前or范围内显示声明,2)用类及其派生类作为参数直接调用

     6.

    --为了避免复制用引用作为参数

    --explicit 修饰构造函数,抑制隐式转换,避免不必要的歧义;   一般都是将只有一个参数的构造函数定义为explict

    // rint.cpp : 定义控制台应用程序的入口点。
    //
    /************************************************************************/
    /* 定义RINT使其像int                                                                     */
    /************************************************************************/
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    struct rint
    {
        rint(int i):i_(i){}
        rint& operator=(int i){i_=i;return *this;}
    private:
        int i_;
        friend rint operator+(rint const&);
        friend rint operator+(rint const&,rint const&);
        friend rint operator-(rint const&);
        friend rint operator-(rint const&,rint const&);
        friend rint operator*(rint const&,rint const&);
        friend rint operator/(rint const&,rint const&);
        friend rint operator%(rint const&,rint const&);
        friend ostream& operator<<(ostream&,rint const&);
    };
    
    rint operator+(rint const& a)
    {
        return a;
    }
    rint operator+(rint const& a,rint const& b)
    {
        return rint(a.i_+b.i_);
    }
    rint operator-(rint const& a)
    {
        return rint(-a.i_);
    }
    rint operator-(rint const& a,rint const& b)
    {
        return rint(a.i_-b.i_);
    }
    rint operator*(rint const& a,rint const& b)
    {
        return rint(a.i_*b.i_);
    }
    rint operator/(rint const& a,rint const& b)
    {
        return rint(a.i_/b.i_);
    }
    rint operator%(rint const& a,rint const& b)
    {
        return rint(a.i_%b.i_);
    }
    
    
    ostream& operator<<(ostream& os,rint const& a)
    {
        os<<a.i_<<endl;
        return os;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        rint ri1=6;
        rint ri2=2;
        cout<<"ri1="<<ri1<<" "<<"ri2="<<ri2<<endl;
        cout<<"+ri1="<<+ri1<<endl;
        cout<<"ri1+ri2="<<ri1+ri2<<endl;
        cout<<"ri1-ri2="<<ri1-ri2<<endl;
        cout<<"ri1*ri2="<<ri1*ri2<<endl;
        cout<<"ri1/ri2="<<ri1/ri2<<endl;
        cout<<"ri1%ri2="<<ri1%ri2<<endl;
        system("pause");
        return 0;
    }
    自定义的简单类int型
    class string
    {//
    public:
    string operator()(int left, int right)
    {
          check(left);check(right);
          if(left<right)
         {
               char *a=new char[right-left+2];
               strcpy(a,str->left,right-left+1);
               a[right-left+1]='0';
               string result(a);
               delete[] a;
               return result;
           }
           else{result string("");}
    }    
    }
    重载(),实现取子串

    总结及忠告:

    1).重载只是为了满足人的习惯,运算符能操作的还是只是内部类型;只不过用operator包装一下而已。

    2).默认复制构造对于类不适合,需要重新定义它,或者将它禁止(声明为private).

    3).将只有一个参数的构造函数做成explicit

  • 相关阅读:
    第四次作业
    软工第三次作业
    第三次作业
    第二次作业
    团队第三次作业:Alpha版本发布
    软件工程团队作业--Alpha版本第二周小结
    软件工程团队作业--Alpha版本第一周小结
    团队第二次作业
    C++多态性总结
    第四次作业:结对编程
  • 原文地址:https://www.cnblogs.com/lp3318/p/mycpp_lp.html
Copyright © 2020-2023  润新知