• 程序设计


    首先我们要理解清楚private属于私有变量只能被本类中的成员函数所引用。类似于Int& Int::operator +=(const Int&rhs)你会发现+=需要两个变量,属于双目运算符,但是形参列表里面只有一个参数,所以很显然他是成员函数。(成员函数的返回值就是本类的类型,形参个数在原来基础上减一)

    但是普通函数,就是通俗讲的普通函数

    譬如:

    const Int operator +(const Int&lhs,const Int& rhs)
    {
        Int ret(lhs);
        ret+=rhs;
        return ret;
    }
    

    因为有些运算符属于单目运算符,它本身就无法利用成员函数重展

    记住:双目运算符建议用非成员函数重载

    流输出运算符建议非成员函数重载

    当然c++规定= 【】 ()必须成员函数重载

    将+= -= /= %= *= &= ^= >>= <<= 单目和算数运算符用成员函数重载

    区别

    :成员函数可以直接调用类中的私有变量

    例如

    Int& Int::operator +=(const Int&rhs)
    {
        value+=rhs.value;
        return *this;
    }
    

    但是普通函数对于类中的private来说是无法调用的所以需要接口函数

    例如

    int getsize()const{return size;}
    

    用成员函数你还可以直接用*this指针调用前面被隐藏的参数(即被剪掉的那个参数)

    Int& Int::operator +=(const Int&rhs)
    {
        this->value+=rhs.value;///你可以写上this,也可以不写
        return *this;///返回时直接返回他的值this只是地址 *this才是提取出来的值
    }
    

    接着要学会区分前缀++和后缀++

    就是说直接按照你理解的 a=1 b=a++ 和b=++a

    这是两个结果,第一个后缀的b=1,因为先赋值后加加

    而前缀的b=2 不妨看下面的代码

    Int& Int::operator ++()///前缀
    {
        ++value;///直接加即可
        return *this;
    }
    Int Int::operator ++(int tmp)///后缀  这里的tmp作为参数无实际效果,只是当作区分 前缀和后缀的参考
    {
        Int ret(*this);///按照上面的理解a还是加了1,但是赋值给b的还是本值
        ++value;///所以先拷贝一份,然后再将a+1,但是返回的是之前的拷贝值
        return ret;
    }
    

    不同位置的const用途

    形参列表中的const 只是为了防止进行拷贝时将形参改变,影响逻辑含义

    最后的const则是说明该函数不允许改变类的成员

    接下来的 get函数 disp函数均要用到

    const Int operator +(const Int&lhs,const Int& rhs)
    {
        Int ret(lhs);
        ret+=rhs;
        return ret;
    }
    int Int::getvalue()const{return value;}
    

    总结

    :+ - * / % 函数均使用const+类名 且不要声明作用域 只有成员函数才需要声明

    而= += *= /= 则是类名加上& 作用域 函数名

    << >>则用普通函数

    关于作用域 只有构造函数 才是类名::函数类型

    其他成员函数都是函数类型 类名::函数名

    int& Array::operator [](int pos)///普通版本
    {
        return data[pos];
    }
    const int& Array::operator [](int pos)const ///之前const用法所讲的
    {
        return data[pos];
    }
    

    总的类

    class Int{
    private:
        int value;
    public:
    
    };
    
    Int::Int():value(0){}///只有构造函数才需要列表初始化,其他函数会报错
    Int::Int(int v):value(v){}///拷贝构造
    Int::Int(const Int& rhs):value(rhs.value){}///拷贝构造
    Int::~Int(){}///析构
    int Int::getvalue()const{return value;}
    void Int::setvalue(int v){value=v;}
    Int& Int::operator =(const Int&rhs)
    {
        if (this!=&rhs)
        {
            this->value=rhs.value;
        }
        return *this;
    }
    Int& Int::operator +=(const Int&rhs)
    {
        value+=rhs.value;
        return *this;
    }
    Int& Int::operator ++()
    {
        ++value;
        return *this;
    }
    Int Int::operator ++(int tmp)
    {
        Int ret(*this);
        ++value;
        return ret;
    }
    const Int operator +(const Int&lhs,const Int& rhs)
    {
        Int ret(lhs);///先调用拷贝构造初始化
        ret+=rhs;
        return ret;
    }
    bool operator ==(const Int&lhs,const Int& rhs)
    {
        return lhs.getvalue()==rhs.getvalue();
    }
    std::ostream& operator <<(std::ostream&os,const Int &rhs)
    {
        return os<<rhs.getvalue();///把os理解为cout即可
    }
    std::istream& operator >>(std::istream&is,const Int& rhs)
    {
        int sum;
        is>>sum;///将is理解为cin
        rhs.setvalue(sum);
        return is;
    }
    
    class Array{
    private:
        enum{SIZE=1000};
        int data[SIZE];
        int size;
    public:
        int getsize()const{return size;}
    };
    Array::Array():size(0){}
    Array::Array(const Array& rhs):size(rhs.size)
    {
        for (int i=0;i<rhs.size;++i)
        {
            data[i]=rhs.data[i];
        }
    }
    Array::Array(const int a[],int n):size(n)
    {
        forr (int i=0;i<n;++i)
        {
            data[i]=a[i];
        }
    }
    Array::Array(int count,int n):size(n)
    {
        forr (int i=0;i<n;++i)
        {
            data[i]=count;
        }
    }
    
    void Array::insert(int pos,int value)
    {
        for(int i=size-1;i>pos;--i)///注意要从后往前,否则前面的会把后面的全部覆盖
        {
            data[i+1]=data[i]
        }
        data[pos]=value;
        ++size;
    }
    
    int Array::at(int pos)const
    {
        return data[pos];
    }
    
    void Array::remove(int pos)
    {
        for (int i=pos;i<size-1;++i)///从前往后,慢慢往前移
        {
            data[i]=data[i+1];
        }
        --size;
    }
    
    void Array::modify(int pos,int newvalue)
    {
        data[pos]=newvalue;
    }
    void Array::disp()const///凡是直接输出值后面均要加const
    {
       for (int i=0;i<size;++i)
       {
          cout<<at(i)<<' ';
       }
       cout<<endl;
    }
    
    Array& Array::operator =(const Array&rhs)
    {
        if (this!=&rhs)
        {
            size=rhs.size;
            for (int i=0;i<size;++i)
            {
                data[i]=rhs.data[i];
            }
        }
        return *this;
    }
    int& Array::operator [](int pos)
    {
        return data[pos];
    }
    const int& Array::operator [](int pos)const 
    {
        return data[pos];
    }
    bool operator <(const Array&lhs,const Array&rhs)
    {
        int n=lhs.getsize();
        if (n>rhs.getsize())
            n=rhs.getsize();
        for(int i=0;i<n;++i)
        {
            if (lhs[i]<rhs[i])return true;
            else if (lhs[i]>rhs[o])return false;
        }
        return lhs.getsize()<rhs.getsize();
    }
    bool operator ==(const Array&lhs,const Array&rhs)
    {
        if (lhs.getsize()!=rhs.getsize())
            return false;
        for(int i=0;i<lhs.getsize();++i)
        {
          if (lhs[i]!=rhs[i])
            return false;
        }
        return true;
    }
    
    const Array operator +(const Array&lhs,const Array&rhs)///两个形参的普通函数 故不要加上作用域
    {
        Array ret(lhs);
        for (int i=0;i<rhs.getsize();++i)
        {
            ret.insert(lhs.getsize(),rhs.at(i));
        }
        return ret;
    }
    
    std::ostream& operator <<(ostream&os,const Array&rhs)
    {
        for(int i=0;i<rhs.getsize();++i)
        {
            os<<rhs.at(i)<<' ';
        }
        return os;
    }
    
    class ArrayList{///大部分和Array类很像,一个用数组,一个new
    private:
        int *data;
        int capacity;
        int size;
    public:
    
    };
    ArrayList::ArrayList():data(0),size(0),capacity(1)
    {
        data=new int[capacity];///new
    }
    ArrayList::ArrayList(const ArrayList&rhs):data(0),size(rhs.size),capacity(rhs.capacity)
    {
       data=new int[capacity];
       for (int i=0;i<size;++i)
       {
        data[i]=rhs.data[i];
       }
    }
    ArrayList::ArrayList(const int a[],int n):data(0),size(n),capacity(n)
    {
        data=new int[capacity];
        for (int i=0;i<n;++i)
        {
            data[i]=a[i];
        }
    }
    ArrayList::ArrayList(int value,int n):data(0),size(n),capacity(n)
    {
        data=new int[capacity];
        for (int i=0;i<n;++i)
        {
            data[i]=value;
        }
    }
    ArrayList::~ArrayList()
    {
       delete []data;///一定要记得析构
    }
    
    
    void ArrayList::setcapacity(int newcapacity)///设置容量
    {
        int *pt=data;///将原来的pt指向data的地址,然后让data进行重新new值
        data= new int[capacity=newcapacity];
        for (int i=0;i<size;++i)
        {
            data[i]=pt[i];///最后把pt指向的原来的data的值返回给新的扩容的data
        }
        delete []pt;///最后要删除原来的pt也就是原来的data的容量
    }
    void ArrayList::insert(int pos,int value)
    {
        if (capacity==size)
        {
            setcapacity(capacity+capacity);///一般扩容两倍
        }
        for (int i=size;i>pos;--i)
        {
            data[i+1]=data[i];
        }
        ++size;
    }
    int ArrayList::at(int pos)
    {
        return data[i];
    }
    void ArrayList::modify(int pos,int newvalue)
    {
        data[i]=newvalue;
    }
    void ArrayList::remove(int pos)
    {
        for (int i=pos;i<size-1;++i)
        {
            data[i]=data[i+1];
        }
        --size;
    }
    ArrayList& ArrayList::operator =(const ArrayList&rhs)
    {
        if (this!=&rhs)
        {
            if (capacity<rhs.size)
            {
                setcapacity(rhs.size);
            }
            for (int i=0;i<rhs.size;++i)
            {
                data[i]=rhs.data[i];
            }
        }
        size=rhs.size;
        return *this;
    }
    bool operator == (const ArrayList&lhs,const ArrayList&rhs)
    {
        if (lhs.getSize()!=rhs.getSize())
         return false;
      int n=lhs.getSize();
      for (int i=0;i<n;++i)
      {
        if (lhs.at(i)!=rhs.at(i))
          return false;
      }
      return true;
    }
    
    ArrayList& ArrayList::operator +=(const ArrayList&rhs)
    {
        if (capacity<rhs.size+size)
        {
            setcapacity(size+rhs.size);
        }
        for(int i=0;i<rhs.size;++i)
        {
          data[i+size]=rhs.data[i];
        }
        size=size+rhs.size;
        return *this;
    } 
    ArrayList&  ArrayList::operator [](int pos)
    {
       return data[pos];
    }
    const ArrayList& ArrayList::operator [](int pos)const
    {
        return data[pos];
    }
    std::ostream& operator << (std::ostream&os,const ArrayList&rhs)
    {
      for (int i=0;i<rhs.getSize();++i)
      {
        os<<rhs[i]<<' ';
      }
      return os;
    }
    
    class LinkedList{///链表的话一开始比较难以理解,你可以把它想象成一些小方格,它们是直线的,
    ///每个相邻的之间有一条线也就是next,首先的话就需要一个空的表头也就是*head,他没有任何逻辑意义,只是说为了能让删除操作和理论一致,保证最后一个元素也能被删除
    public:
        struct Node{
            int data;
            Node *next;
            Node (int a,Node *b):data(a),next(b){}
        };
    public:
        Node *head;
        int size;
    };
    LinkedList::LinkedList():head(0),size(0)
    {
        head=new Node(0,0);///初始化
    }
    LinkedList::LinkedList(const LinkedList&rhs):head(0),size(rhs.size)
    {
        head=new Node(0,0);
        Node *q=head;///先建立表头
        for(Node *p=rhs.head->next///第一个元素;p,p=p->next)///你把他理解为
    ///for(int i=;i<n;++i)就可以了
        {
            q->next=new Node(p->data,0);
        }
    }
    LinkedList::LinkedList(const int a[],,int n):head(0),size(n)
    {
       head=new Node(0,0);
       Node *q=head;
       for(int i=0;i<n;++i)
       {
            q->next=new Node(a[i],0);
            q=q->next;
       }
    }
    LinkedList::LinkedList(int value,,int n):head(0),size(n)
    {
       head=new Node(0,0);
       Node *q=head;
       for(int i=0;i<n;++i)
       {
            q->next=new Node(value,0);
            q=q->next;
       }
    }
    LinkedList::~LinkedList()
    {
        Node *p,*q;
        q=head;
        p=head->next;
        delete q;///先析构表头之后慢慢往后移
        while(p)
        {
            q=p;
            p=p->next;
            delete q;
        }
    }
    
    LinkedList:: Node* LinkedList::advance(int pos)const
    {
        Node *p=head;///由于最先的一个是空的表头,所以要从-1开始
        for (int i=-1;i<pos;++i)
        {
            p=p->next;
        }
        return p;
    }
    
    int LinkedList::at(int pos)const
    {
        Node *p=advance(pos);
        return p->data;
    }
    void LinkedList::remove(int pos)///自己画个图,三个格子删除中间那个
    ///前面的格子的next直接指向第三个格子就行
    {
        Node *p=advance(pos-1);
        Node *q=p->next;
        p->next=q->next;
        --size;
    }
    
    void LinkedList::insert(int pos,int value)
    {
        Node *p=advance(pos-1);
        Node *q=new Node(value,p->next);///插入稍微麻烦点,先建立一个格子,这个格子指向原来的两个格子之间,
    ///先将原来第一个格子指向后面格子的next,转为新格子指向后一个格子,再将前面的格子next指向新格子  画图你就理解了
        p->next=q;
        ++size;
    }
    void LinkedList::modify(int pos,int newvalue)
    {
        Node *p=advance(pos);
        p->data=newvalue;
    }
    
    void LinkedList::disp()const
    {
      for (LinkedList::Node *p=this->head->next;p;p=p->next)///这里要特别注意,因为disp是普通函数,现在他调用的是NOde是属于类里面的所以需要声明作用域
      {
        cout<<p->data<<' ';
      }
      cout<<endl;
    }
    
    LinkedList& LinkedList::operator =(const LinkedList&rhs)
    {
      if (&rhs!=this)
      {
        while (0!=size)remove(0);
        Node *q=head;
        for (Node *p=rhs.head->next;p;p=p->next)
        {
          q->next = new Node(p->data,0);
          q = q->next;
        }
        size = rhs.size;
      }
      return *this;
    }
    
    LinkedList& LinkedList::operator +=(const LinkedList&rhs)
    {
      Node *p = advance(size-1);
      for (Node *rp=rhs.head->next;rp;rp=rp->next)
      {
        Node *q = new Node(rp->data,0);
        p->next = q;
        p = q;
      }
      size+=rhs.size;
      return *this;
    }
    int& LinkedList::operator [] (int pos)
    {
      Node*p = advance(pos);
      return p->data;
    }
    const int& LinkedList::operator [] (int pos)const
    {
      Node*p = advance(pos);
      return p->data;
    }
    int LinkedList::compareTo(const LinkedList&rhs)const
    {
     int n=size;
     int m=rhs.size;
     n=min(m,n);
     for(int i=0;i<n;++i){
          if(advance(i)->data<rhs.advance(i)->data)return -1;
          if(advance(i)->data>rhs.advance(i)->data)return 1;
     }
      if (size<rhs.size)
        return -1;
      else if (size==rhs.size)
        return 0;
      else
        return 1;
    }
    void LinkedList::disp(ostream&os)const
    {
         for(int i=0;i<size;++i){
                os<<advance(i)->data<<" ";
            }
    }
    
    

    你会发现只有个别的例如析构函数有所区别其他的不尽相同,所以自行理解。时间来不及画图,望谅解。

    最后祝各位考试顺利。

    齐芒行,川锋明!
  • 相关阅读:
    Springboot演示小Demo
    快速构建一个 Springboot
    javase练习题--每天写写
    javase练习题
    WebDriver API——延时操作及元素等待
    WebDriver API——javascript的相关操作
    Jenkins安装部署及tomcat的入门介绍
    WebDriver API——鼠标及键盘操作Actions
    sql查询练习
    睡前反省,絮叨絮叨
  • 原文地址:https://www.cnblogs.com/qimang-311/p/13198664.html
Copyright © 2020-2023  润新知