【C++】模版类实现普通类静态顺序表

原创 2016年05月30日 17:17:57

    在C或C++里,我们已经学会了如何实现一个静态顺序表了,那为何还要引入模版类来实现静态顺序表呢?首先,我们看,在未引入模版前,我们在C++里是这样定义一个静态顺序表的:

typedef int DataType;    //此时我定义的是int型

class SeqList
{
    DataType* _array;
    size_t _size;
    size_t _capacity;
}

    我们若要定义char型或者其他类型的,可以采用typedef了,这就是使用typedef的优势之处。另外,还利于统一管理程序代码,增加代码的可维护性。


    可是,有时候我们会不会遇到这样的问题呢:

void Test()
{
    SeqList s1;    //此时s1我想定义成为char型
    SeqList s2;    //此时s2我想定义成为非char型
}

    这时候,若我们使用typedef换来换去的,难免使得代码混乱或者出错。若是再定义一个类来实现另外一个类型的静态顺序表,这时候代码两处相似度极高,也不利于维护。因此,我们引入模板,模板类的实例化可以轻而易举地解决好这个问题。

代码如下:


#include<iostream>
using namespace std;
#include<string>
#include<assert.h>

template<class T>

class SeqList
{
private:
    T* _array;
    size_t _size;
    size_t _capacity;
    
public:
    SeqList()
        :_array(NULL)
        , _size(0)
        , _capacity(0)
    {}

    SeqList(const SeqList<T>& s)
    {
        _array = new T[s._size];
        for (size_t i = 0; i < s._size; i++)
        {
            _array[i] = s._array[i];
        }
        _size = s._size;
        _capacity = s._size;
    }

    SeqList<T>& operator=(SeqList<T> s)
    {
        if (&s != this)
        {
            swap(_array, s._array);
            swap(_size, s._size);
            swap(_capacity, s._capacity);
        }
        return *this;
    }

    ~SeqList()
    {
        if (_array)
        {
            delete[] _array;
        }
    }

    //扩容
    void _CheckCapacity(size_t n)
    {
        if (n > _capacity)
        {
            _capacity = n > 2 * _capacity + 3 ? n : 2 * _capacity + 3;
            /*_array = (T*)realloc(_array, sizeof(T)* _capacity);*/
            //不可行!realloc对于自定义类型未调用构造函数初始化对象,随机值会崩溃。
            
            T* tmp = new T[_capacity];
            if (_array)
            {
                /*memcpy(tmp, _array, sizeof(T)* _size);*/
                //不可行!对于长字符串重新开辟空间拷贝析构两次崩溃
                for (size_t i = 0; i < _size; i++)
                {
                    tmp[i] = _array[i];
                }
            }
            delete[] _array;
            _array = tmp;
        }
    }

    //打印
    void PrintSeqList()
    {
        for (size_t i = 0; i < _size; i++)
        {
            cout << _array[i] << "  ";
        }  
        cout << endl;
    }

    //尾插
    void PushBack(const T& x)
    {
        _CheckCapacity(_size + 1);
        _array[_size++] = x;
    }

    //operator[]
    T& operator[](size_t index)
    {
        assert(index < _size);
        return _array[index];
    }

    //请求空间
    void Reserve(size_t n)
    {
        _CheckCapacity(n);
    }
};

void Test()
{
    SeqList<int> s1;
    s1.PushBack(1);
    s1.PushBack(2);
    s1.PushBack(3);
    s1.PushBack(4);
    s1.PushBack(5);
    s1.PrintSeqList();

    SeqList<string> s2;
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PushBack("xxx");
    s2.PrintSeqList();
            
    SeqList<string> s3(s2);
    s3[0] = "yyy";
    s3.PrintSeqList();    
}


int main()
{
    Test();
    system("pause");
    return 0;
}

    在这里,我们关注下reserve()函数,接口实现请求一个容量。我们查看cplusplus.com可以找vector(顺序表)中的reserve(size_t n)。n表示开辟多大的空间。

    其他的函数之前的博客实现过,我们这里就不再重复实现了。



本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1750309

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

c++基础之:可拓展顺序表模版类

#include #include using namespace std; template class ToozyList { public: ToozyLis...

静态代码块、代码块、构造方法、普通方法&父类、子类顺序

1、子类main方法的内容: new HelloA(); 控制台: Static A 父类的静态代码块 static B 子类的静态代码块 I am A Class 父类的代码块 He...

C/C++开发语言系列之4---普通继承和虚基类构造函数的初始化顺序1

1、虚基类的作用从上面的介绍可知:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。 在引用这些同名的成员时,必须在派...

C++类的三种数据成员:常量(const)、静态(static)、普通 的赋值方式

讲解了C++类的三种数据成员【常量(const)、静态(static)、普通】的正确赋值姿势

顺序表结构的模版类

List.h #ifndef LIST_H #define LIST_H #define MAXSIZE 100 #include using namespace std; template c...

C++类模版:带表头链表的实现

链表的概念链表是常用的基本数据结构之一,属于线性表。同属于线性表的还有顺序表,我们常说的数组就是顺序表。 带表头链表链表的实现有带表头和不带表头两种方式。最原始的方式,也就是不带表头的实现方式,是用...

【C++数据结构】模版类实现双循环链表的基本操作

单链表结构为我们提供方便分数据插入和删除工作,美中不足的是查询数据不方便,对于单链表查找数据至少要遍历一边.  为此我们提出双链表结构,从而方便的查询数据. 给出双链表的一般结构: 一...

9秒学院C++模版类实现单链表

先上代码 /********************************线性表抽象类的定义***************************/ template class list{...

c++链表实现队列,深搜加宽搜,加模版类实现迷宫问题;

数据结构作业二,用链表实现队列,用深搜宽搜解决迷宫问题,另是模版类的用法; 模版类用法举例: 栗子一:template class Node{ public: bbb data; ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)