VS2013 编写-类模板-代码 -编译出错

laimanyou 2015-04-16 05:27:21
LinkList.h如下:

#include <iostream>
#include <assert.h>
#include <stdafx.h>
using namespace std;

template <class type>
class ListNode{
public:
ListNode(){next = NULL;}
ListNode(const type & item, ListNode<type> *next1 = NULL){
data = item;
next = next1;
}
type data;
ListNode<type> * next;
};

template <class type>
class LinkList{
public:
LinkList(){
head = new ListNode<type>;
length = 0;
}
LinkList(LinkList<type> & L){
Copy(1);
}
~LinkList(){
MakeEmpty();
delete head;
}
ListNode<type> * GetHead() {return head;} //获得表头节点指针
ListNode<type> * GetNext(ListNode<type> & n) {return n.next == head?n.next->next:n.next;} //获得节点n的下一个节点位置
type GetData(int i); //取出链表中的第i个元素
bool SetData(type value, int i); //将链表中的第i个元素赋值为value
ListNode<type> * FindByVal(type value); //找到值为value的节点指针
ListNode<type> * FindByPos(int pos); //找到链表中第pos个节点指针
void MakeEmpty(); //清空整个链表

bool Insert(type value, int i); //在第i个位置插入值为value的节点
type RemoveByPos(int pos); //删除掉位置pos处的节点
type RemoveByVal(type value); //删除掉值为value的节点

LinkList<type> & Copy(LinkList<type> &L); //拷贝函数
LinkList<type> & operator = (LinkList<type> &L); //重载赋值运算符,同类型链表赋值
friend ostream & operator <<(ostream &out, LinkList<type> &L); //重载输出运算符
protected:
ListNode<type> * head;
int length;
};

//类模板中函数的实现如下:
template <class type>
ListNode<type> * LinkList<type>::FindByVal(type value){
ListNode<type> *p = head->next;
int i = 1;
while(i++ <= length && value != p->data)
p = p->next;
return p;
}

template <class type>
ListNode<type> * LinkList<type>::FindByPos(int pos){
if(pos < 0 || pos > length) return NULL;
if(pos == 0) return head;
ListNode<type> *p = head->next;
int i = 1;
while(i++ < pos && p!= NULL)
p = p->next;
return p;
}

template <class type>
type LinkList<type>::GetData(int pos){
ListNode<type> *p = FindByPos(pos);
assert(p && p != head);
return p->data;
}

template <class type>
bool LinkList<type>::SetData(type value, int pos){
ListNode<type> *p = FindByPos(pos);
if(!p || p == head)
return false;
else
p->data = value;
return true;
}

template <class type>
void LinkList<type>::MakeEmpty(){
ListNode<type> *p = head->next;
int i = 1;
while(i++ <= length){
head->next = p->next;
delete p;
p = head->next;
}
length = 0;
}

template <class type>
bool LinkList<type>::Insert(type value, int i){
ListNode<type> *p = FindByPos(i-1);
if(!p) return false;
ListNode<type> *node = new ListNode<type> (value,p->next);
assert(node);
p->next = node;
length++;
return true;
}

template <class type>
type LinkList<type>::RemoveByPos(int pos){
ListNode<type> *p = FindByPos(pos-1), *q;
assert(p && p->next != NULL);
q = p->next;
type val = q->data;
p->next = q->next;
delete q;
length--;
return val;
}

template <class type>
type LinkList<type>::RemoveByVal(type val){
ListNode<type> *p, *q = head;
p = q->next;
while((p->next != NULL) && (p->next->data != val)){
p = p->next;
}
q = p->next;
p->next = q->next;
delete q;
length--;
return val;
}

template <class type>
LinkList<type> & LinkList<type>::Copy(LinkList<type> &L){
if(! L.head)
return *this;
ListNode<type> *p = NULL, *q = NULL, *r = NULL;
this->length = L.length;
head = new ListNode<type>;
assert(head);
head->data = L.head->data;
head->next = NULL;
p = head;
q = L.head->next;
while(q){
r = new ListNode<type>;
if(r == NULL)
return *this;
r->data = q->data;
r->next = NULL;
p->next = r;
q = q->next;
p = p->next;
}
return *this;
}

template <class type>
LinkList<type> & LinkList<type>::operator = (LinkList<type> &L){
if(head)
MakeEmpty();
Copy(L);
return *this;
}

template <class type>
ostream & operator <<(ostream &out, LinkList<type> & L){
ListNode<type> *p = L.head->next;
out<<"length:"<<L.length<<"\ndata:";
while(p){
out<<p->data<<" ";
p = p->next;
}
out<<"\n";
return out;
}


main.cpp如下:

#include <iostream>
#include "LinkList.h"
#include <stdafx.h>
using namespace std;

int main()
{
LinkList< int > m_list;
m_list.Insert(3,1);
m_list.Insert(2,2);
m_list.Insert(4,3);
cout<<m_list<<endl;
return 0;
}


编译错误提示有:(全在main.cpp)
error C2062:意外的类型int 第8行
error C2065 未声明的标示符 cout endl LinkList m_list
error C2228 .Insert左边必须有类/结构/集合

类模板的定义和实现已经放在了同一个文件(必须是.cpp吗?)中,为何还是会有上述错误呢?
...全文
222 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
laimanyou 2015-04-17
  • 打赏
  • 举报
回复
引用 9 楼 lsq19871207 的回复:
实际上,在声明的时候你这样写也是可以的:

friend ostream& operator<< <> (ostream &out, LinkList<type>& L);
//等同于:
friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);
你可以试试! <>之所以必不可少,是因为<>表明此友元函数是函数模板,在模板类中重装<<操作符时必不可少的 另外,<>中啥也不写你可以理解为此模板函数使用的模板类型参数为当前模板类的类型参数class type
多谢多谢!受教了!
信阳毛尖 2015-04-16
  • 打赏
  • 举报
回复
实际上,在声明的时候你这样写也是可以的:

friend ostream& operator<< <> (ostream &out, LinkList<type>& L);
//等同于:
friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);
你可以试试! <>之所以必不可少,是因为<>表明此友元函数是函数模板,在模板类中重装<<操作符时必不可少的 另外,<>中啥也不写你可以理解为此模板函数使用的模板类型参数为当前模板类的类型参数class type
laimanyou 2015-04-16
  • 打赏
  • 举报
回复
引用 7 楼 lsq19871207 的回复:
[quote=引用 2 楼 VisualEleven 的回复:] friend ostream & operator <<(ostream &out, LinkList<type> &L); ----> friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);
说的是!就是<<操作符的问题,改成版猪的吧[/quote] 嗯哪!
信阳毛尖 2015-04-16
  • 打赏
  • 举报
回复
引用 2 楼 VisualEleven 的回复:
friend ostream & operator <<(ostream &out, LinkList<type> &L); ----> friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);
引用 1 楼 lsq19871207 的回复:
看不出什么问题来,把cout<<m_list<<endl;这句去掉试试
说的是!就是<<操作符的问题,改成版猪的吧
laimanyou 2015-04-16
  • 打赏
  • 举报
回复
引用 5 楼 VisualEleven 的回复:
// LinkList.h 文件
#pragma once

#include <iostream>
#include <assert.h>

using namespace std;

template <class type> 
class LinkList;

template <class type> 
ostream& operator<<(ostream &out, LinkList<type>& L);


friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);  //重载输出运算符


template <class type> 
ostream& operator<<(ostream &out, LinkList<type>& L){
	ListNode<type> *p = L.head->next;
	out<<"length:"<<L.length<<"\ndata:";
	while(p){
		out<<p->data<<" ";
		p = p->next;
	}
	out<<"\n";
	return out;
}
十分感谢版主你,问题已破。 然后请问:简单地说就是因为重载<<的函数没有提前声明? 为何类定义中的<type>不可或缺,而另外两个地方没有也行?
Eleven 2015-04-16
  • 打赏
  • 举报
回复
// LinkList.h 文件
#pragma once

#include <iostream>
#include <assert.h>

using namespace std;

template <class type> 
class LinkList;

template <class type> 
ostream& operator<<(ostream &out, LinkList<type>& L);

template <class type>
class ListNode{
public:
	ListNode(){next = NULL;}
	ListNode(const type & item, ListNode<type> *next1 = NULL){
		data = item;
		next = next1;
	}
	type data;
	ListNode<type> * next;
};

template <class type>
class LinkList{
public:
	LinkList(){
		head = new ListNode<type>;
		length = 0;
	}
	LinkList(LinkList<type> & L){
		Copy(1);
	}
	~LinkList(){
		MakeEmpty();
		delete head;
	}
	ListNode<type> * GetHead() {return head;}   //获得表头节点指针
	ListNode<type> * GetNext(ListNode<type> & n) {return n.next == head?n.next->next:n.next;}   //获得节点n的下一个节点位置
	type GetData(int i);    //取出链表中的第i个元素
	bool SetData(type value, int i);    //将链表中的第i个元素赋值为value
	ListNode<type> * FindByVal(type value);     //找到值为value的节点指针
	ListNode<type> * FindByPos(int pos);    //找到链表中第pos个节点指针
	void MakeEmpty();   //清空整个链表

	bool Insert(type value, int i);     //在第i个位置插入值为value的节点
	type RemoveByPos(int pos);  //删除掉位置pos处的节点
	type RemoveByVal(type value);   //删除掉值为value的节点

	LinkList<type> & Copy(LinkList<type> &L);   //拷贝函数
	LinkList<type> & operator= (LinkList<type> &L);    //重载赋值运算符,同类型链表赋值
	friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);  //重载输出运算符

protected:
	ListNode<type> * head;
	int length;
};

//类模板中函数的实现如下:
template <class type>
ListNode<type> * LinkList<type>::FindByVal(type value){
	ListNode<type> *p = head->next;
	int i = 1;
	while(i++ <= length && value != p->data)
		p = p->next;
	return p;
}

template <class type>
ListNode<type> * LinkList<type>::FindByPos(int pos){
	if(pos < 0 || pos > length) return NULL;
	if(pos == 0) return head;
	ListNode<type> *p = head->next;
	int i = 1;
	while(i++ < pos && p!= NULL)
		p = p->next;
	return p;
}

template <class type>
type LinkList<type>::GetData(int pos){
	ListNode<type> *p = FindByPos(pos);
	assert(p && p != head);
	return p->data;
}

template <class type>
bool LinkList<type>::SetData(type value, int pos){
	ListNode<type> *p = FindByPos(pos);
	if(!p || p == head)
		return false;
	else
		p->data = value;
	return true;
}

template <class type>
void LinkList<type>::MakeEmpty(){
	ListNode<type> *p = head->next;
	int i = 1;
	while(i++ <= length){
		head->next = p->next;
		delete p;
		p = head->next;
	}
	length = 0;
}

template <class type>
bool LinkList<type>::Insert(type value, int i){
	ListNode<type> *p = FindByPos(i-1);
	if(!p) return false;
	ListNode<type> *node = new ListNode<type> (value,p->next);
	assert(node);
	p->next = node;
	length++;
	return true;
}

template <class type>
type LinkList<type>::RemoveByPos(int pos){
	ListNode<type> *p = FindByPos(pos-1), *q;
	assert(p && p->next != NULL);
	q = p->next;
	type val = q->data;
	p->next = q->next;
	delete q;
	length--;
	return val;
}

template <class type>
type LinkList<type>::RemoveByVal(type val){
	ListNode<type> *p, *q = head;
	p = q->next;
	while((p->next != NULL) && (p->next->data != val)){
		p = p->next;
	}
	q = p->next;
	p->next = q->next;
	delete q;
	length--;
	return val;
}

template <class type>
LinkList<type> & LinkList<type>::Copy(LinkList<type> &L){
	if(! L.head)
		return *this;
	ListNode<type> *p = NULL, *q = NULL, *r = NULL;
	this->length = L.length;
	head = new ListNode<type>;
	assert(head);
	head->data = L.head->data;
	head->next = NULL;
	p = head;
	q = L.head->next;
	while(q){
		r = new ListNode<type>;
		if(r == NULL)
			return *this;
		r->data = q->data;
		r->next = NULL;
		p->next = r;
		q = q->next;
		p = p->next;
	}
	return *this;
}

template <class type>
LinkList<type> & LinkList<type>::operator = (LinkList<type> &L){
	if(head)
		MakeEmpty();
	Copy(L);
	return *this;
}

template <class type> 
ostream& operator<<(ostream &out, LinkList<type>& L){
	ListNode<type> *p = L.head->next;
	out<<"length:"<<L.length<<"\ndata:";
	while(p){
		out<<p->data<<" ";
		p = p->next;
	}
	out<<"\n";
	return out;
}
// main.cpp
#include <iostream>
#include "LinkList.h"

using namespace std;

int main()
{
	LinkList< int > m_list;
	m_list.Insert(3,1);
	m_list.Insert(2,2);
	m_list.Insert(4,3);
	cout<<m_list<<endl;
	return 0;
}
laimanyou 2015-04-16
  • 打赏
  • 举报
回复
引用 3 楼 VisualEleven 的回复:
#include <stdafx.h> 这个都去掉
去掉之后错误都没了,然后我添加了<type>,提示我说:非法使用显示模板参数。 遂去掉。 然后错误提示:main.obj errorLNK2019:无法解析的外部符号"class std::basic_ostream<char,struct ....>"该符号在函数_main中被引用。注释掉cout<<m_list那句后就没事了。 重载<<符还有什么没注意到的呢?
Eleven 2015-04-16
  • 打赏
  • 举报
回复
#include <stdafx.h> 这个都去掉
Eleven 2015-04-16
  • 打赏
  • 举报
回复
friend ostream & operator <<(ostream &out, LinkList<type> &L); ----> friend ostream& operator<< <type> (ostream &out, LinkList<type>& L);
信阳毛尖 2015-04-16
  • 打赏
  • 举报
回复
看不出什么问题来,把cout<<m_list<<endl;这句去掉试试

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧