zoukankan      html  css  js  c++  java
  • C++Array类模板编写笔记

    C++Array类模板

             函数模板和类模板都属于泛型技术,利用函数模板和类模板来创建一个具有通用功能的函数和类,以支持多种不同的形参,从而进一步简化重载函数的函数体设计。

            声明方法:template<typename/class 标识符(T)>

            函数声明(通用形参使用标识符(T)代替)

    //Array.h
    #ifndef ARRAY_H
    #define ARRAY_H
    #include<cassert>
    
    template<class T>
    class Array
    {
    private:
        T* m_list;
        int m_size;
    
    public:
        //构造函数
        Array(int sz=50);
        //拷贝构造函数
        Array(const Array<T>&a);
        //析构函数
        ~Array();
        //重载“=”可以让数组对象整体赋值
        Array<T>& operator=(const Array<T>& rhs);
        //重载“[]”使Array对象可以索引指定位置数据
        T& operator[](int i); //此处必须返回引用,若返回值,则无法直接进行运算,变量使用完毕后便被销毁
        //“[]”针对const的重载
        const T& operator[](int i) const;
        //重载T*类型转换
        operator T*();
        //“T*”针对const的重载
        operator const T*() const;
        //获取数组大小
        int getSize() const;
        //改变数组大小
        void resize(int sz);
    };
    
    template<class T>
    Array<T>::Array(int sz)
    {
        assert(sz);
        m_size=sz;
        m_list=new T[m_size];
    }
    
    template<class T>
    Array<T>::Array(const Array<T>& a)
    {
        //浅复制
        m_size=a.m_size;
        m_list=a.m_list;
        //深复制
        m_size=a.m_size;
        m_list=new T[m_size];
        for (int i = 0; i < m_size; i++)
        {
            m_list[i]=a.m_list[i];
        }
    }
    
    template<class T>
    Array<T>::~Array()
    {
        delete[] m_list;
    }
    
    template<class T>
    Array<T>& Array<T>::operator=(const Array<T>& chs)
    {
        if (&chs!=this)
        {
            if (chs.m_size!=this.m_size)
            {
                delete[] m_list;
                m_size=chs.m_size;
                m_list=new T[m_size];
            }
            for (int i = 0; i < m_size; i++)
                {
                    this.m_list[i]=chs.m_list[i];
                }
        }
        return *this;
    }
    
    template<class T>
    //此处引用有两点:1.不能返回临时变量,否则引用无值索引;2.此处必须为引用,若为值类型,操作数必须为左值。
    T& Array<T>::operator[](int i)
    {
        assert(i>=0&&i<m_size);
        //有待测试
        /*T temp=m_list[i];
        return temp;*/
        return m_list[i];
    }
    
    template<class T>
    Array<T>::operator T*()
    {
        return m_list;
    }
    
    template<class T>
    int Array<T>::getSize() const
    {
        return m_size;
    }
    
    template<class T>
    void Array<T>::resize(int sz)
    {
        assert(sz>=0);
        if (sz==m_size)
        {
            return;
        }
        else
        {
            T* Newlist=new T[sz];
            int n=(m_size<sz)?m_size:sz;
            for (int i = 0; i < n; i++)
            {
                Newlist[i]=m_list[i];
            }
            delete[] m_list;
            m_list=Newlist;
            m_size=sz;
            delete[] Newlist;
        }
    }
    #endif

               在本次我编写的Array类模板中,可以看出类模板的本质还是函数模板构成的。同时,在此次编写类模板的过程中,深刻地体会了C++的三个知识点。

    分别是拷贝构造函数的深复制与浅复制成员函数与非成员函数运算符重载返回值与返回引用的区别。接下来,将详细说这三个知识点。

    1. 拷贝构造函数的深复制与浅复制:拷贝构造函数,是以对象的引用作为形参,并用const常量约束。若对象为头指针和线性空间存储数据的形式,浅复制,则是只复制了头指针和空间大小,而未真正意义上实现线性空间的数据复制;而深复制,则将被复制对象的线性空间所有的数据依次赋予对象。
    2. 成员函数运算符重载和非成员函数运算符重载的区别:成员函数在二目运算符中,只需要一个形参,另外一个为本对象的this指针;而非成员函数在二目运算符中,则需要两个形参。
    3. 返回值与返回引用的区别:返回值,即生成了return变量的拷贝,在使用后,临时变量就将被销毁。因此,返回值后不能做左值运算。返回引用,即生成对return变量的别名,可对此变量操作,进行左值运算。但返回引用,返回的不能是临时变量,必须是类成员变量局部静态变量传入的引用形参
  • 相关阅读:
    Pascal's Triangle 2(leetcode java)
    118. Pascal's Triangle (java)
    Bulb Switcher (leetcode java)
    Lowest Common Ancestor of a Binary Search Tree(Java 递归与非递归)
    Remove Duplicate Letters(Java 递归与非递归)
    读大道至简有感
    自学Java第一周的总结
    jmeter----jpgc----ultimate thread group
    jmeter----jpgc----stepping thread group
    jmter--jpgc模块
  • 原文地址:https://www.cnblogs.com/dzw2017/p/8312925.html
Copyright © 2011-2022 走看看