我正在编写一个用于创建Card对象链接列表的赋值,并且在编译时遇到了链接器错误。在Deck类cpp中,我获得了对重载<<<<<<<<运算符和Card的LinkedList构造函数。我尝试在Dev C ++和g ++中进行编译
在开发中我收到以下错误:
C:\Users\Chris\Dropbox\mohroo-2a\Deck.o Deck.cpp:(.text+0x1c): undefined reference to `operator<<(std::ostream&, LinkedList<Card> const&)'
C:\Users\Chris\Dropbox\mohroo-2a\Deck.o Deck.cpp:(.text+0x3e): undefined reference to `LinkedList<Card>::LinkedList()'
c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe C:/Users/Chris/Dropbox/mohroo-2a/Deck.o: bad reloc address 0x0 in section `.pdata'
c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\bin\ld.exe final link failed: Invalid operation
F:\Documents\collect2.exe [Error] ld returned 1 exit status
在g ++中:
In file included from Deck.h:4:0,
from Deck.cpp:1:
LinkedList.h:9:76: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const LinkedList<T>&)’ declares a non-template function [-Wnon-template-friend]
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<T> &l);
^
LinkedList.h:9:76: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
In file included from LinkedList.cpp:1:0:
LinkedList.h:9:76: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const LinkedList<T>&)’ declares a non-template function [-Wnon-template-friend]
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<T> &l);
^
LinkedList.h:9:76: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
In file included from Deck.h:4:0,
from program.cpp:2:
LinkedList.h:9:76: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const LinkedList<T>&)’ declares a non-template function [-Wnon-template-friend]
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<T> &l);
^
LinkedList.h:9:76: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
/tmp/cc3tT0cD.o:Deck.cpp:(.text+0x1c): undefined reference to `operator<<(std::ostream&, LinkedList<Card> const&)'
/tmp/cc3tT0cD.o:Deck.cpp:(.text+0x1c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `operator<<(std::ostream&, LinkedList<Card> const&)'
/tmp/cc3tT0cD.o:Deck.cpp:(.text+0x3e): undefined reference to `LinkedList<Card>::LinkedList()'
/tmp/cc3tT0cD.o:Deck.cpp:(.text+0x3e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LinkedList<Card>::LinkedList()'
/usr/lib/gcc/x86_64-pc-cygwin/4.8.1/../../../../x86_64-pc-cygwin/bin/ld: /tmp/cc3tT0cD.o: bad reloc address 0x0 in section `.pdata'
collect2: error: ld returned 1 exit status
以下是代码:
加入deck.h
#ifndef DECK_H
#define DECK_H
#include <ostream>
#include "LinkedList.h"
#include "Card.h"
class Deck
{
friend std::ostream &operator<<(std::ostream &ostr, const Deck &d);
public:
Deck();
private:
LinkedList<Card> theDeck;
Node<Card> *top;
};
#endif
Deck.cpp
#include "Deck.h"
std::ostream &operator<<(std::ostream &ostr, const Deck &d)
{
ostr << d.theDeck;
return ostr;
}
Deck::Deck()
{
}
LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <ostream>
#include "Node.h"
template <typename T>
class LinkedList
{
template <typename K>
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l);
public:
LinkedList();
~LinkedList();
void addNode(Node<T> *newNode);
Node<T> *head;
};
template <typename T>
LinkedList<T>::LinkedList()
{
head = 0;
}
template <typename T>
LinkedList<T>::~LinkedList()
{
Node<T> *ptr = head;
while(ptr != 0)
{
Node<T> *temp = ptr->next;
delete ptr;
ptr = temp;
}
}
template <typename T>
void LinkedList<T>::addNode( Node<T> *newNode)
{
Node<T> *ptr = head;
while(ptr != 0)
{
ptr = ptr->next;
}
ptr->next = newNode;
}
template <typename K>
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l)
{
ostr << "[ ";
Node<T> *ptr = l.head;
while(ptr != 0)
{
ostr << ptr->data << " ";
ptr = ptr->next;
}
ostr << "]";
return ostr;
}
#endif
Node.h
#ifndef NODE_H
#define NODE_H
template <typename T>
class Node
{
public:
Node();
Node(const T &nodeData);
Node(const Node<T> *nextNode);
Node(const T &nodeData, const Node *nextNode);
T data;
Node *next;
};
template <typename T>
Node<T>::Node()
:data()
{
next = 0;
}
template <typename T>
Node<T>::Node(const T &nodeData)
{
data = nodeData;
next = 0;
}
template <typename T>
Node<T>::Node(const Node<T> *nextNode)
:data()
{
next = nextNode;
}
template <typename T>
Node<T>::Node(const T &nodeData, const Node *nextNode)
{
data = nodeData;
next = nextNode;
}
#endif
Card.h
#ifndef CARD_H
#define CARD_H
#include <ostream>
class Card
{
friend std::ostream &operator << (std::ostream &ostr, const Card &c);
private:
int value; //Ranges from 2-14, where Ace = 14, Jack = 11, Queen = 12, King = 13
int suit; //Ranges from 1-4, where 1 = Clubs, 2 = Diamonds, 3 = Hearts, 4 = Spades
public:
Card();
Card(int, int);
Card operator=(const Card &crd);
Card (const Card &obj);
void setValue(int);
void setSuit(int);
int getValue();
int getSuit();
};
#endif
Card.cpp
#include "Card.h"
std::ostream &operator<<(std::ostream &ostr, const Card &c)
{
switch(c.value)
{
case 2:
ostr << "Two";
break;
case 3:
ostr << "Three";
break;
case 4:
ostr << "Four";
break;
case 5:
ostr << "Five";
break;
case 6:
ostr << "Six";
break;
case 7:
ostr << "Seven";
break;
case 8:
ostr << "Eight";
break;
case 9:
ostr << "Nine";
break;
case 10:
ostr << "Ten";
break;
case 11:
ostr << "Jack";
break;
case 12:
ostr << "Queen";
break;
case 13:
ostr << "King";
break;
case 14:
ostr << "Ace";
break;
}
ostr << " of ";
switch(c.suit)
{
case 1:
ostr << "Clubs";
break;
case 2:
ostr << "Diamonds";
break;
case 3:
ostr << "Hearts";
break;
case 4:
ostr << "Spades";
break;
}
return ostr;
}
Card::Card()
{
value = 0;
suit = 0;
};
Card::Card(const Card &obj)
{
value = obj.value;
suit = obj.suit;
};
Card Card::operator=(const Card &crd)
{
suit = crd.suit;
value = crd.value;
return *this;
};
Card::Card(int tvalue, int tsuit)
{
value = tvalue;
suit = tsuit;
};
void Card::setValue(int tempValue)
{
value = tempValue;
}
void Card::setSuit(int tempSuit)
{
suit = tempSuit;
}
int Card::getValue()
{
return value;
}
int Card::getSuit()
{
return suit;
}
最后是program.cpp
#include <iostream>
#include "Deck.h"
using namespace std;
int main()
{
Card someCard(2,4);
Card otherCard(14,1);
cout << someCard << "\n" << otherCard << endl;
}
那么任何想法?我试过看起来这看起来像链接器错误但是当我使用g++ *.cpp -o main
进行编译时会产生上述错误。我接下来要做什么了。提前致谢
编辑:
LinkedList.h现在看起来像这样
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <ostream>
#include "Node.h"
template <typename T>
class LinkedList
{
template <typename K>
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l);
public:
LinkedList();
~LinkedList();
void addNode(Node<T> *newNode);
Node<T> *head;
};
template <typename T>
LinkedList<T>::LinkedList()
{
head = 0;
}
template <typename T>
LinkedList<T>::~LinkedList()
{
Node<T> *ptr = head;
while(ptr != 0)
{
Node<T> *temp = ptr->next;
delete ptr;
ptr = temp;
}
}
template <typename T>
void LinkedList<T>::addNode( Node<T> *newNode)
{
Node<T> *ptr = head;
while(ptr != 0)
{
ptr = ptr->next;
}
ptr->next = newNode;
}
template <typename K>
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l)
{
ostr << "[ ";
Node<T> *ptr = l.head;
while(ptr != 0)
{
ostr << ptr->data << " ";
ptr = ptr->next;
}
ostr << "]";
return ostr;
}
#endif
答案 0 :(得分:2)
除了如上所述,模板必须在头文件中,实际问题是友元函数实际上不在类的范围内,所以你不能使用typename T,它可以隐藏类的类型名称。使用另一个,尝试K :
template <typename T>
class LinkedList
{
template <typename K>
friend std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l);
...
您仍然可以使用T来实现运算符。如果使用K:
template <typename K>
std::ostream &operator<<(std::ostream &ostr, const LinkedList<K> &l)
{
ostr << "[ ";
Node<K> *ptr = l.head;
答案 1 :(得分:0)
您应该在头文件中编写所有模板类。编译器在编译.cpp文件时不知道您将使用哪些类作为模板,因此它根本不生成任何内容。