C++数据结构之线性表的顺序结构实现(cannot declare variable ‘..‘ to be of abstract type ‘....‘处理)

线性表的顺序结构实现

代码实现

  • 抽象基类AbstractList.h文件
template<class T>
class AbstractList
{
    
    
public:
    virtual bool isEmpty() const=0;
    virtual int length() const=0;
    virtual bool findElement(int k,T& x)const =0;
    //find the element whose index is k and assign the result to the x
    virtual int searchElement(const T& x)const =0;
    //search the x element and return its index
    virtual AbstractList<T>& delete(int k,T& x)=0;
    //delete the x element ,return the deleted Linklist and return the deleted element
    virtual AbstractList<T>& insert(int k,const T& x)=0;
    //insert the element at the position whose index is k
    virtual void output() const=0;
};
分析与总结
  • 使用“virtual … =0”的方式去声明纯虚函数,而在结尾加上对应的const,则表明该成员函数并不能够对类的成员进行修改

  • 对于大型的数据量,要尽量调用的引用来进行传值,减少内存消耗

  • 如果不需要修改形参的值,可在形参前面加上const,声明为的常量

  • LinerList.h文件

#ifndef _LINERLIST_H
#define _LINERLIST_H

#include "AbstractList.h"
#include <iostream>

using namespace std;

template <class T>
class LinerList:public AbstractList<T>
{
    
    
public:
    LinerList(int maxSize=10);
    ~LinerList(){
    
    delete []element;}
    bool isEmpty()const{
    
    return length==0;};
    int getLength()const {
    
    return length;};
    bool findElement(int k,T& x)const;
    //find the element whose index is k and assign the result to the x
    int searchElement(const T& x)const;
    //search the x element and return its index
    AbstractList<T>& Delete(int k,T& x);
    //delete the x element ,return the deleted Linklist and return the deleted element
    AbstractList<T>& insert(int k,const T& x);
    //insert the element at the position whose index is k
    void output() const;
    AbstractList<T>& add(const T& x);
private:
    int length;
    int maxSize;
    T* element;
};

template <class T>
LinerList<T>::LinerList(int maxSize)
{
    
    
    element = new T[maxSize];
    this->maxSize = maxSize;
    length = 0;
}

//find the element whose index is k and assign the result to the x
template <class T>
bool LinerList<T>::findElement(int k,T& x)const
{
    
    
    if(k<0 || k>length)
    {
    
    
        cout<<"error:out of index!"<<endl;
        return false;
        //the result of the function is the type of bool
    }
    //the index of array is from zero!
    x = element[k-1];
    return true;
    //the reference cannot be changed!
    //the meaning of the = is copy not change the reference!
}

//search the x element and return its index
template<class T>
int LinerList<T>::searchElement(const T& x)const
{
    
    
    if(isEmpty()) return -1;
    //for the illegal value use illegal value to represent for!
    for(int i = 0;i < length;i++)
    {
    
    
        if(element[i] == x)
        {
    
    
            return ++i;
            //caution:the index of the LinerList is one more than array!
        }
    }
    return -1;
}

//delete the x element ,return the deleted Linklist and return the deleted element
template<class T>
AbstractList<T>& LinerList<T>::Delete(int k,T& x)
{
    
    

    if(findElement(k,x))
    {
    
    
        for(int i = k; i < length; i ++) {
    
    
            element[i-1] = element[i];

        }
        length --;
        return *this;
    }
    else
    {
    
    
        cout<<"out of the index"<<endl;
        return *this;
    }
    //almost forget it
}

//insert the element at the position whose index is k
template<class T>
AbstractList<T>& LinerList<T>::insert(int k,const T& x)
{
    
    
    if(!(length == 0 && k == 1))
    {
    
    
        if(k>length || k<1) {
    
    
            cout<<"out of the index!"<<endl;
            return *this;

        }
        int i = 0;
        //move and copy the revelant element
        for(i = length - 1; i >= k-1 && i >= 0; i --) {
    
    
            element[i + 1] = element[i];
        }
        //insert the element in the targeted position
    }
    element[k - 1] = x;
    length ++;
    return *this;
}

template <class T>
void LinerList<T>::output() const
{
    
    
    cout<<"the length of the LinerList is:"<<length<<endl;
    cout<<"List is:";
    for(int i = 0;i < length;i ++)
    {
    
    
        cout<<element[i]<<"    ";
    }
    cout<<endl;
}

template <class T>
AbstractList<T>& LinerList<T>::add(const T& x)
{
    
    
    if(length == maxSize)
    {
    
    
        cout<<"out of memeory!add the element absortively"<<endl;
        return *this;
    }
    element[length] = x;
    length ++;
    return *this;
}

#endif // _LINERLIST_H
  • main测试文件
#include <iostream>
#include "LinerList.h"

using namespace std;

int main()
{
    
    
    LinerList<int> L(5);
    cout<<"length:"<<L.getLength()<<endl;
    cout<<"is empty:"<<L.isEmpty()<<endl;
    L.add(1).add(2).add(3).add(4);
    L.output();
    L.insert(1,8).insert(1,88);
    L.output();
    int z;
    L.findElement(1,z);
    cout<<"the found element is:"<<z<<endl;
    L.Delete(3,z);
    cout<<"the deleted element is : "<<z<<endl;

    return 0;
}

在这里插入图片描述

分析与总结

  • 引用是没有办法被修改的,而对引用使用赋值符号,并不是将修改引用的指向,是将等号的左边的对象的属性,完全复制到等号的右边的对象的属性。注意对等号的理解
  • 注意下标:对于使用者而言,下标是从1开始的,但是对于程序而言,下标是从0开始的!彼此转换,记得加一减一。用户输入的索引是从1开始的,程序员是从零开始,注意两者之间的转换
  • 学会使用异常处理机制,来替代单纯的输入输出语句
  • 编写程序的过程注意分步处理,按照情况进行分类

遇到的异常

cannot declare variable ‘…’ to be of abstract type ‘…’
  • 没有彻底实现所有的虚函数——漏了const的常量的声明
    • 只需要加上对应的const常量声明即可
      在这里插入图片描述
      在这里插入图片描述
udefined reference to ‘…’
  • 对于模板类而言,C++中部分编译器,不支持声明.h和实现.cpp分开写——只需要将之整合到一个文件中即可

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/108931396