0

我知道那里有很多类似的问题 - 相信我,我已经阅读过它们 - 但我无法让它发挥作用。这很奇怪,因为前几天我用一个相关程序解决了一个类似的问题。我意识到我的问题的答案很可能在某个地方,但我花了一两个小时寻找,但没有取得多大成功。

我正在尝试建立一个链接列表。该程序由四个文件组成——链表和节点的头文件,以及链表的接口,以及包含 main 方法的 .cpp 文件。

ListTester.cpp

#include "StdAfx.h"
#include "LinkedList.h"
#include <iostream>
#include <string>

using namespace std;

template <typename T>
void main() {

    LinkedList<int> a;
    a.addFirst(22);
    a.addFirst(24);
    a.addFirst(28);
    LinkedList<int> b;
    b = a;
    b = b + a;
    b += a;

    cout<<b;
}

链表.h

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h"
#include "List.h"
#include <ostream>

template <typename T>

class LinkedList : public List {

private:

    int n;
    Node<T> *first;
    Node<T> *last;

public:

    LinkedList();
    LinkedList(const LinkedList & ll);
    ~LinkedList();
    int size();
    void clear();
    void addFirst(T data);
    void addLast(T data);
    T removeFirst();
    T removeLast(); 
    T getFirst();
    T getLast();
    Node<T>* getFirstNode() const;
    void addAt(int pos, T data);
    T removeAt(int pos);
    T getAt(int pos);   
    LinkedList& operator=(const LinkedList<T> &right);
    T operator[](int i);
    LinkedList& operator+(const LinkedList<T> &right);
    LinkedList& operator+=(const LinkedList<T> &right);
    friend std::ostream& operator<<(std::ostream &os, const LinkedList<T> & ll);

};

template <typename T>
LinkedList<T>::LinkedList() {
        this->n = 0;
        this->first = 0;
        this->last = 0;
    }

template <typename T>
LinkedList<T>::LinkedList(const LinkedList & ll) {
    this-> n = 0;
    this-> first = 0;
    this-> last = 0;

    Node *temp = ll.first;

    while(temp) {
        addLast(temp->getData());
        temp = temp->getNext();
    }

}

template <typename T>
void LinkedList<T>::addFirst(T data) {
    Node *p = new Node(data, first);
    first = p;
    if(!n)
        last = p;
    n++;
}

template <typename T>
void LinkedList<T>::addLast(T data) {
    Node *p = new Node(data, 0);
    if(!n)
        first = last = p;
    else {
        last->next = p;
        last = p;
    }
    n++;
}

template <typename T>
T LinkedList<T>::removeFirst() {
    T a = 0;
    if(!n)
        throw "Can't retrieve element from empty list!";
    a = first->getData();
    Node *p = first->next;
    delete first;
    first = p;
    n--;
    return a;
}

template <typename T>
T LinkedList<T>::removeLast() {
    T a = 0;
    if(!n)
        throw "Can't retrieve element from empty list!";
    if(n == 1) {
        a = last->getData();
        delete first;
        first = last = 0;
    }
    else {
        a = last->getData();
        Node *p = first;
        while(p->next->next != 0)
            p = p->next;
        delete p->next;
        p->next = 0;
        last = p;
    }
    n--;
    return a;
}

template <typename T>
T LinkedList<T>::getFirst() {
    if(n < 1)
        throw "Can't retrieve element from empty list!";
    return first->getData();
}

template <typename T>
T LinkedList<T>::getLast() {
    if(n < 1)
        throw "Can't retrieve element from empty list!";
    return last->getData();
}

template <typename T>
Node<T>* LinkedList<T>::getFirstNode() const {
    return first;
}

template <typename T>
int LinkedList<T>::size() {
    return n;
}

template <typename T>
T LinkedList<T>::getAt(int pos) {
    if(pos >= n)
        throw "Element index out of bounds!";       
    Node *temp = first;
    while(pos > 0) {
        temp = temp->next;
        pos--;
    }
    return temp->getData();     
}

template <typename T>
void LinkedList<T>::clear() {
    Node *current = first;
    while(current) {
        Node *next = current->next;
        delete current;
        if(next)
            current = next;
        else
            current = 0;
    }
}

template <typename T>
void LinkedList<T>::addAt(int pos, T data) {
    if(pos >= n)
        throw "Element index out of bounds!";       
    if(pos == 0)
        addFirst(data);
    else {
        Node *temp = first;
        while(pos > 1) {
            temp = temp->next;
            pos--;
        }
        Node *p = new Node(data, temp->next);
        temp-> next = p;
        n++;
    }
}

template <typename T>
T LinkedList<T>::removeAt(int pos) {
    if(pos >= n)
        throw "Element index out of bounds!";       
    if(pos == 0)
        return removeFirst();
    if(pos == n - 1)
        return removeLast();
    else {
        Node *p = first;
        while(pos > 1) {
            p = p->next;
            pos--;
        }
        T a = p->next->getData();
        Node *temp = p->next;
        p->next = p->next->next;
        delete temp;
        n--;
        return a;
    }       
}

template <typename T>
LinkedList<T>::~LinkedList() {
    clear();
}

template <typename T>
LinkedList<T>& LinkedList<T>::operator=(const LinkedList<T> &right) {
    if(this != &right) {

        n = 0;
        first = 0;
        last = 0;

        Node *temp = right.first;
        while(temp) {
            addLast(temp->getData());
            temp = temp->getNext();
        }           
    }
    return *this;
}

template <typename T>
T LinkedList<T>::operator[](int i) {
    return getAt(i);
}

template <typename T>
LinkedList<T>& LinkedList<T>::operator+(const LinkedList<T> &right) {
    Node *temp = right.first;
    while(temp) {
        addLast(temp->getData());
        temp = temp->getNext();
    }
    return *this;
}

template <typename T>
LinkedList<T>& LinkedList<T>::operator+=(const LinkedList<T> &right) {
    Node *temp = right.first;
    while(temp) {
        addLast(temp->getData());
        temp = temp->getNext();
    }
    return *this;
}

template <typename T>
std::ostream& operator<<(std::ostream &os, const LinkedList<T> &ll) {
    Node *temp = ll.getFirstNode();
    while(temp) {
        os<<temp->getData()<<std::endl;
        temp = temp->getNext();
    }
    return os;
}

#endif

节点.h

#ifndef NODE_H
#define NODE_H

template <typename T>
class Node {

private:

    T data;

public:

    Node<T>* next;
    T getData();
    Node<T>* getNext();
    Node(T data, Node<T>* next);
    Node(const Node & n);

};

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

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

template <typename T>
Node<T>::Node(T data, Node<T>* next) {
    this->data = data;
    this->next = next;
    }

template <typename T>
Node<T>::Node(const Node & n) {
    data = n.data;
    next = n.next;
}   

#endif

列表.h

#ifndef LIST_H
#define LIST_H

class List
  {

public:

    virtual void addFirst(int data) = 0;
    virtual void addAt(int pos, int data) = 0;
    virtual void addLast(int data) = 0;
    virtual int getFirst()= 0;
    virtual int getAt(int pos) = 0;
    virtual int getLast()= 0;
    virtual int removeFirst()= 0;
    virtual int removeAt(int pos) = 0;
    virtual int removeLast()= 0;
    virtual int size() = 0;
    virtual void clear() = 0;
    virtual ~List() {};     

  };

#endif

为此,我收到 LNK2019 和 LNK1120 链接错误。我知道我曾经在分离的 .h 和 .cpp 文件中实现队列时得到这个。但是通过在标题中做所有事情来解决它。我也知道在不实现命名方法时会发生这种情况,但我在这里找不到任何方法。那么是什么原因造成的呢?我希望编译器/IDE 可以指出错误的可能原因。但是话又说回来,如果找到故障线路很容易,我认为它已经做到了。VS 2012 顺便说一句。

4

2 回答 2

2
// template <typename T>
void main() {

    LinkedList<int> a;
    a.addFirst(22);
    a.addFirst(24);
    a.addFirst(28);
    LinkedList<int> b;
    b = a;
    b = b + a;
    b += a;

    cout<<b;
}

您需要一个主函数,而不是一个主函数模板。这可能是您的链接器错误的来源:没有名为“main”的函数。

这不起作用的原因主要是因为类模板和函数模板永远不会扩展到实际代码,除非它们被使用。由于 main 是您程序的入口点,因此您永远不会从任何地方调用 main,因此不会生成 main 代码。

此外,由于 C++ 编译器对函数(处理重载、模板、命名空间等)的名称修改,将在生成的程序集中为该主模板生成的符号可能不是正确的符号。如果它正在寻找一个符号'main'并且它看到

$__T_float_main_blah_blah_blah

那么你无论如何都不会链接。长话短说: main 是一个函数,而不是函数模板。

于 2013-03-27T13:14:10.297 回答
2

你制作main了一个函数模板。这不仅没有意义(里面没有提到模板参数),而且它也从未实例化(即使是,它也可能无法正确解析main程序作为起点所需的正确性)。

此外,它应该是int main而不是void main

于 2013-03-27T13:14:22.043 回答