C ++对List <int> :: GetCount()const </int>的未定义引用

时间:2013-09-12 16:22:03

标签: c++ templates codeblocks

我正在编写一个简单的数据结构库,而我遇到了一些问题。

我写了三个文件。 collections.h是头文件,collections.cpp用于实现头文件中声明的方法,main.cpp用于测试。但是发生了编译错误:

对List :: GetCount()const;

的未定义引用

对List :: IsEmpty()const;

的未定义引用

对List :: Add(int);

的未定义引用

... //等等。

我在下面提供了我的代码,问题在哪里?

collections.h:

#ifndef COLLECTIONS_H
#define COLLECTIONS_H

#include <windows.h>
#include <stdexcept>

template<typename T>
class ISequenceList
{
protected:
    ISequenceList() { }
public:
    virtual int GetCount() const = 0;
    virtual bool IsEmpty() const = 0;
    virtual void Add(T item) = 0;
    virtual void AddRange(const T *items, int length) = 0;
    virtual T &ElementAt(int index);
    virtual bool InsertAt(T item, int index);
    virtual bool Remove(T item) = 0;
    virtual bool RemoveAt(int index) = 0;
    virtual bool Contains(T item) = 0;
};

template<typename T>
class List : public ISequenceList<T>
{
private:
    int _count;
    int _capacity;
    T *_array;

    void ExpandCapacity();
public:
    List(int capacity = 100)
    {
        if (capacity <= 0)
            std::__throw_invalid_argument("The capcity can't be 0 or below.");
        this->_count = 0;
        this->_capacity = capacity;
        this->_array = (T*)malloc(_capacity* sizeof(T));
    }
    List(const List &other)
    {
        if (this == other)
            return;
        this->_count = other->_count;
        this->_capacity = other->_capacity;
        free(_array);
        this->_array = other->_array;
    }
    List &operator=(const List &other)
    {
        this = other;
    }
    ~List()
    {
        if (_array)
            free(_array);
    }

    int GetCount() const;
    bool IsEmpty() const;
    T &ElementAt(int index);
    void Add(T item);
    void AddRange(const T *items, int length);
    bool InsertAt(T item, int index);
    bool Remove(T item);
    bool RemoveAt(int index);
    bool Contains(T item);
};

#endif

collections.cpp:

#include "collections.h"

template<typename T>
void List<T>::ExpandCapacity()
{
    T *temp = this->_array;
    this->_array = (T*)malloc((this->_capacity << 1) * sizeof(T));
    memcpy(this->_array, temp, this->_capacity * sizeof(T));
    this->_capacity = this->_capacity << 1;
    free(temp);
}

template<typename T>
int List<T>::GetCount() const
{
    return this->_count;
}

template<typename T>
bool List<T>::IsEmpty() const
{
    return this->_count == 0;
}

template<typename T>
void List<T>::Add(T item)
{
    this->_array[_count] = item;
    _count++;
    if (_count == _capacity)
        this->ExpandCapacity();
}

template<typename T>
void List<T>::AddRange(const T *items, int length)
{
    if (length <= 0)
        std::__throw_invalid_argument("The length can't be 0 or below.");
    if (!items)
        std::__throw_invalid_argument("The items can't be null");
    int totalLength = this->_count + length;
    if (totalLength >= this->_capacity)
    {
        T *temp = this->_array;
        this->_array = (T*)malloc((totalLength << 1) * sizeof(T));
        memcpy(_array, temp, this->_capacity);
        free(temp);
    }
    this->_array += this->_capacity;
    memcpy(_array, items, length * sizeof(T));
    this->_capacity = totalLength << 1;
    this->_count += length;
}

template<typename T>
T &List<T>::ElementAt(int index)
{
    if (index < 0 || index >= _count )
        std::__throw_invalid_argument("The index is out of bound.");
    return _array[index];
}

template<typename T>
bool List<T>::InsertAt(T item, int index)
{
    if (index < 0 || index > _count)
        return false;
    if (index == _count)
    {
        this->Add(item);
        return true;
    }
    for (int i = _count; i > index; i--)
    {
        _array[i] = _array[i - 1];
    }
    _array[index] = item;
    _count++;
    if (_count == _capacity)
        this->ExpandCapacity();
    return true;
}

template<typename T>
bool List<T>::Remove(T item)
{
    for (int i = 0; i < _count; i++)
    {
        if (_array[i] == item)
        {
            for (int j = i; j < _count; j++)
            {
                _array[j] = _array[j + 1];
            }
            _count--;
            return true;
        }
    }
    return false;
}

template<typename T>
bool List<T>::RemoveAt(int index)
{
    if (index < 0 || index >= _count)
        return false;
    for (int j = index; j < _count; j++)
    {
        _array[j] = _array[j + 1];
    }
    _count--;
    return true;
}

template<typename T>
bool List<T>::Contains(T item)
{
    for (int i = 0; i < _count; i++)
    {
        if (_array[i] == item)
            return true;
    }
    return false;
}

main.cpp中:

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

int main()
{
    List<int> *seqList = new List<int>();
    seqList->Add(5);
    int arr[100] = {0};
    seqList->AddRange(arr, 50);
    seqList->ElementAt(5) = 111;
    seqList->InsertAt(100, 15);
    seqList->Remove(50);
    seqList->ElementAt(44) = 44;
    seqList->RemoveAt(44);
    if (seqList->Contains(111))
        std::cout << "Yes" << std::endl;

    for (int i = 0; i < seqList->GetCount(); i++)
    {
        std::cout << seqList->ElementAt(i) << "\t";
    }

    return 0;
}

我已经定义了List中的所有方法,但为什么编译器不能识别呢?问题出在哪儿?感谢任何帮助我的人..

注意:我的ide是Code :: Blocks

1 个答案:

答案 0 :(得分:3)

模板函数的实现必须在标题中;它不能在单独的源文件中。编译器需要在使用模板并且其参数已知的位置看到它。