模板类数据类型

时间:2014-06-05 18:00:34

标签: c++

我创建了这个非常简单的动态列表,它使用模板类实现:

Node.h

template <class T> class Node
{
public:
    typedef T data_type;
    typedef T& reference_type;

    void setData(data_type);
    void setNextNull();
    void setNext(Node*);

    reference_type getData();
    Node* getNext();

private:
    data_type data;
    Node* next;
};

template <class T> void Node<T>::setData(data_type _data)
{
    data=_data;
}

template <class T> void Node<T>::setNextNull()
{
    next=NULL;
}

template <class T> void Node<T>::setNext(Node* _next)
{
    next=_next;
}

template <class T> typename Node<T>::reference_type Node<T>::getData()
{
    return data;
}

template <class T> typename Node<T>::Node* Node<T>::getNext()
{
    return next;
}

List.h

#ifndef LIST_H
#define LIST_H

#include <Node.h>

template <class T> class List
{
public:
    typedef Node<T> node_type;
    typedef node_type* node_pointer;
    typedef T data_type;
    typedef T& reference_type;

    List();
    void push_back(data_type);
    reference_type at(int);
    void clear();
    void swap(int,int);
    int size();

private:
    int list_size = 0;
    node_pointer head, tail;
};

template <class T> List<T>::List()
{
    head=NULL;
}

template <class T> void List<T>::push_back(data_type data)
{
    if(head == NULL) {
        head = new node_type;
        head->setData(data);
        tail = head;
    } else {
        node_pointer temp = new node_type;
        temp->setData(data);
        temp->setNextNull();
        tail->setNext(temp);
        tail = tail->getNext();
    }
    list_size++;
}

template <class T> typename List<T>::reference_type List<T>::at(int x)
{
    node_pointer pointer=head;
    for(int i=0; i<x; i++)
        pointer=pointer->getNext();

    return pointer->getData();
}

template <class T> void List<T>::clear()
{
    node_pointer pointer = head;
    for(int i=0; i<list_size; i++) {
        node_pointer temp = pointer;
        pointer=pointer->getNext();
        delete(temp);
    }
    head=NULL;
    list_size=0;
}

template <class T> void List<T>::swap(int x, int y)
{
    data_type buffer=at(x);
    at(x)=at(y);
    at(y)=buffer;
}

template <class T> int List<T>::size()
{
    return list_size;
}

#endif // LIST_H

该列表适用于任何形式的数据类型,除非我在其构造函数中使用带参数的类,然后我收到此错误:

  

include / Node.h错误:没有匹配函数来调用'Player :: Player()'

我做错了什么?

更新1

我按照建议添加了一个简单的构造函数,但是我得到了相同的错误

template <class T> Node<T>::Node(data_type _data)
{
    data=_data;
}

2 个答案:

答案 0 :(得分:1)

您可能尚未为Player类定义默认构造函数。只需插入一个空构造函数

Player() {}

你的问题可能会得到解决。

当您编写模板方法并在主函数中使用它时,如下所示:

Node<Player>

编译器自动调用Player类的构造函数。 如果未在Player中定义任何构造函数,则编译器将使用默认构造函数。但是,您定义的任何构造函数都将隐藏默认构造函数并强制您使用此构造函数。

例如,像

这样的构造函数
Player(string, int, int)

阻止您创建如下对象:

Player *p = new Player();

但是,如果你还没有编写构造函数,那么上面的代码就可以了。

这就是为什么你的模板需要一个默认的构造函数, iff 你定义了一个参数化的构造函数。

答案 1 :(得分:0)

你的班级Node应该有一个T的构造函数,这样你就可以通过复制来构造你的T而不是要求有一个默认的构造函数和副本。

您的Node类将类似于:

template <class T>
class Node
{
public:
    Node(const T& data) : data(data), next(0) {}
    void setNextNull();
    void setNext(Node*);

    const T& getData() const { return data; }
    T& getData() { return data; }
    Node* getNext();

private:
    T data;
    Node* next;
};

所以你转换

head = new node_type;
head->setData(data);

通过

head = new node_type(data);