#ifndef Node_H
#define Node_H
template<typename T>
class Node
{
public:
Node( int =0 );
Node( const Node& );
~Node();
friend istream& operator>> ( istream&, Node<T>& );
friend ostream& operator<< ( const ostream&, const Node& );
protected:
Node* next;
T number;
};
其中友元函数代码
template<typename T>
istream& operator>> ( istream& input, Node<T>& temp )
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
template<typename T>
ostream& operator<< ( const ostream& output, const Node<T>& temp )
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
main函数
#include<iostream>
#include<ctime>
using namespace std;
#include"myList.h"
int main()
{
Node<int> a(5);
cin >> a;
cout << a;
}
出错信息
1>main.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > const &,class Node<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV01@ABV?$Node@H@@@Z),该符号在函数 _main 中被引用
1>main.obj : error LNK2019: 无法解析的外部符号 "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class Node<int> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Node@H@@@Z),该符号在函数 _main 中被引用
谢谢啊
17 个解决方案
#1
1.将友元函数的实现放到类里面去。
2.或者将声明改为:
template<class S> friend istream& operator>> ( istream&, Node<S>& );
template<class S> friend ostream& operator<< ( const ostream&, const Node<S>& );
2.或者将声明改为:
template<class S> friend istream& operator>> ( istream&, Node<S>& );
template<class S> friend ostream& operator<< ( const ostream&, const Node<S>& );
#2
up++
********************************************************************************
* C++经典之作下载链接: http://blog.csdn.net/jerryjbiao/article/details/7358796 *
********************************************************************************
#3
友元函数要先在类模板Node前面声明,在声明友元函数之前,还要先进行类模板Node的声明,
friend ostream& operator<< ( const ostream&, const Node& );这一条语句的第二个函数参数Node是类模板,不是类,改为:const Node<T> &
Node* next; 这一条语句也有错,Node是类模板,不是类,改为:Node<T> *next;
你的头文件中的代码修改如下:
下面是友元函数的定义:
friend ostream& operator<< ( const ostream&, const Node& );这一条语句的第二个函数参数Node是类模板,不是类,改为:const Node<T> &
Node* next; 这一条语句也有错,Node是类模板,不是类,改为:Node<T> *next;
你的头文件中的代码修改如下:
#ifndef Node_H
#define Node_H
#include <iostream>
using std::istream;
using std::ostream;
template<Typename T>
class Node;
template<Typename T>
istream &operator >>(istream &,Node<T> &);
template<Typename T>
ostream &operator <<(ostream &,const Node<T> &);
template<Typename T>
class Node
{
public:
Node( int =0 );
Node( const Node& );
~Node();
friend istream &operator >> <>(istream &,Node<T> &);
friend ostream &operator << <>(ostream &,const Node<T> &);
protected:
Node<T> *next;
T number;
};
下面是友元函数的定义:
template<Typename T>
istream &oprator >> <>(istream &input, Node<T> &temp)
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
ostream &operator << <>(ostream &output,const Node<T> &temp)
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#4
额,,那个S代表我定义的类Node?,,我还试了就字母S,就是不行啊,,具体说按我原来的代码怎么改呢,,谢谢
#5
按我的改,可以运行的
#6
你还要实现类模板Node的构造函数,在main函数所在的源文件中实现,其代码如下:
template<typename T>
Node<T>::Node( int n = 0):number(n)
{}
#7
额,,刚改完,,和你一模一样除了在第二个函数定义时,多个 template<typename T>外,,,但问题还是一样。。
如果去掉那句,,问题更多
#8
你把头文件的名字写出来:然后把头文件里的代码全部贴出来,
然后再把类模板的定义和友元函数的定义所在的文件名字写出来,把源文件的全部代码贴出来
再帮你改
然后再把类模板的定义和友元函数的定义所在的文件名字写出来,把源文件的全部代码贴出来
再帮你改
#9
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
你友元函数中的代码有问题,比如:Node *p = temp.next;都没为指针p分配空间,就使用了,按照我的改,模板格式是没错的
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
你友元函数中的代码有问题,比如:Node *p = temp.next;都没为指针p分配空间,就使用了,按照我的改,模板格式是没错的
#10
好吧,,麻烦了
//typename_Node.h
#ifndef Node_H
#define Node_H
#include<iostream>
using namespace std;
using std::istream;
using std::ostream;
template<typename T>
class Node;
template<typename T>
istream &operator >>( istream &,Node<T> &);
template<typename T>
ostream &operator <<( ostream &,const Node<T> &);
template<typename T>
class Node
{
public:
Node( int =0 );
Node( const Node& );
~Node();
friend istream& operator>> ( istream&, Node<T>& );
friend ostream& operator<< ( ostream&, const Node<T>& );
protected:
Node<T> *next;
T number;
};
template<typename T>
Node<T>::Node( int length )
{
if( length <= 0 )
{
cout << "length wrong ! ";
exit(0);
}
Node* p = next = NULL;
number = 0;
for( int i=1; i<length; i++ )
{
p = new Node;
p->number = 0;
p = p->next;
}
p = NULL;
}
template<typename T>
Node<T>::Node( const Node& mylist )
{
if( mylist.next == NULL )
{
next = '\0';
number = 0;
return ;
}
Node *p1, *p2;
number = mylist.number;
p1 = next;
p2 = mylist.next
while( p2!=NULL )
{
p1->number = p2->number;
p1 = p1->next;
p2 = p2->next;
}
}
template<typename T>
Node<T>::~Node()
{
number = 0;
if( next==NULL )
return;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete p;
}
}
template<typename T>
istream &operator>> <>( istream &input, Node<T> &temp )
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
template<typename T>
ostream &operator<< <>( ostream &output, const Node<T> &temp )
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#endif
#11
我构造函数里的int是要建立链表的长度,,不是里面的数number大小。
我还准备重载[]的,,可以像数组那样使用的,,不过我自己看书太模糊。。。谢啦
#12
上面是你用到的头文件,你的源文件的代码呢,也贴出来,不然的话,头文件的代码修改了,源文件的代码没改,没保持一致也会编译错误的
#13
按照下面的修改,编译是没问题的,也就是语法和格式是正确的,至于功能的实现,要把代码全部贴出来才能知道,不知你用的是什么编译器,我用的是VS2008的编译器。
头文件的代码修改如下:
头文件的代码修改如下:
//typename_Node.h
#ifndef Node_H
#define Node_H
#include <iostream>
using std::ostream;
using std::istream;
using std::cin;
using std::cout;
template<typename T>
class Node;
template<typename T>
istream &operator >>( istream &,Node<T> &);
template<typename T>
ostream &operator <<( ostream &,const Node<T> &);
template<typename T>
class Node
{
public:
Node( int =0 );
Node( const Node<T>& );
~Node();
friend istream& operator>> <>( istream&, Node<T>& );
friend ostream& operator<< <>( ostream&, const Node<T>& );
protected:
Node<T> *next;
T number;
};
template<typename T>
Node<T>::Node( int length = 0 )
{
if( length <= 0 )
{
cout << "length wrong ! ";
exit(0);
}
Node* p = next = NULL;
number = 0;
for( int i=1; i<length; i++ )
{
p = new Node;
p->number = 0;
p = p->next;
}
p = NULL;
}
template<typename T>
Node<T>::Node( const Node<T>& mylist )
{
if( mylist.next == NULL )
{
next = '\0';
number = 0;
return ;
}
Node *p1, *p2;
number = mylist.number;
p1 = next;
p2 = mylist.next
while( p2!=NULL )
{
p1->number = p2->number;
p1 = p1->next;
p2 = p2->next;
}
}
template<typename T>
Node<T>::~Node()
{
number = 0;
if( next==NULL )
return;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete p;
}
}
template<typename T>
istream &operator>> <>( istream &input, Node<T> &temp )
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
template<typename T>
ostream &operator<< <>( ostream &output, const Node<T> &temp )
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#endif
#14
感谢啊,,我把一些其他毛病改过后,,差不多了,,但是析构有点问题。。不明白,,感觉很对啊。。
帮忙看下啊
template<typename T>
Node<T>::~Node()
{
number = 0;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete[] p;
}
}
可以输入输出,,但是最后会有问题。。改为delete p;也不行
如果没有析构,,让计算机析构就没有问题了
我的cpp
//main.cpp
#include<iostream>
#include<ctime>
using namespace std;
#include"myList.h"
int main()
{
Node<int> a(5);
cin >> a;
cout << a;
}
其中#include<ctime>是为以后功能准备的,,可以忽视
再次感谢啊
#15
你想实现的功能是不是建立一个单链表啊?但你的构造函数有问题的,看下面的这个循环;
for( int i=0; i<length; i++ )
{
p = new Node;
p->number = i;
p = p->next;
}
第一个循环是,你的传递的参数length是5,可以执行,但当第二次循环时,执行到P =new Node是,又会调用构造函数,而且使用的默认值,此时length = 0;就会执行exit(0);推出循环,你需要修改构造函数和析构函数
for( int i=0; i<length; i++ )
{
p = new Node;
p->number = i;
p = p->next;
}
第一个循环是,你的传递的参数length是5,可以执行,但当第二次循环时,执行到P =new Node是,又会调用构造函数,而且使用的默认值,此时length = 0;就会执行exit(0);推出循环,你需要修改构造函数和析构函数
#16
不知道到底你的程序想实现什么功能?说具体点,你想干什么
#17
嗯,,就是有这个问题呢。。
我就是想建立一个单链表,,然后会加上其他功能。。
好吧,,已经都麻烦你了,,剩下的我自己搞定吧。。对于类模板中重载输入输出,我已经查到一些资料了。。
太感谢了
#1
1.将友元函数的实现放到类里面去。
2.或者将声明改为:
template<class S> friend istream& operator>> ( istream&, Node<S>& );
template<class S> friend ostream& operator<< ( const ostream&, const Node<S>& );
2.或者将声明改为:
template<class S> friend istream& operator>> ( istream&, Node<S>& );
template<class S> friend ostream& operator<< ( const ostream&, const Node<S>& );
#2
up++
********************************************************************************
* C++经典之作下载链接: http://blog.csdn.net/jerryjbiao/article/details/7358796 *
********************************************************************************
#3
友元函数要先在类模板Node前面声明,在声明友元函数之前,还要先进行类模板Node的声明,
friend ostream& operator<< ( const ostream&, const Node& );这一条语句的第二个函数参数Node是类模板,不是类,改为:const Node<T> &
Node* next; 这一条语句也有错,Node是类模板,不是类,改为:Node<T> *next;
你的头文件中的代码修改如下:
下面是友元函数的定义:
friend ostream& operator<< ( const ostream&, const Node& );这一条语句的第二个函数参数Node是类模板,不是类,改为:const Node<T> &
Node* next; 这一条语句也有错,Node是类模板,不是类,改为:Node<T> *next;
你的头文件中的代码修改如下:
#ifndef Node_H
#define Node_H
#include <iostream>
using std::istream;
using std::ostream;
template<Typename T>
class Node;
template<Typename T>
istream &operator >>(istream &,Node<T> &);
template<Typename T>
ostream &operator <<(ostream &,const Node<T> &);
template<Typename T>
class Node
{
public:
Node( int =0 );
Node( const Node& );
~Node();
friend istream &operator >> <>(istream &,Node<T> &);
friend ostream &operator << <>(ostream &,const Node<T> &);
protected:
Node<T> *next;
T number;
};
下面是友元函数的定义:
template<Typename T>
istream &oprator >> <>(istream &input, Node<T> &temp)
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
ostream &operator << <>(ostream &output,const Node<T> &temp)
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#4
额,,那个S代表我定义的类Node?,,我还试了就字母S,就是不行啊,,具体说按我原来的代码怎么改呢,,谢谢
#5
按我的改,可以运行的
#6
你还要实现类模板Node的构造函数,在main函数所在的源文件中实现,其代码如下:
template<typename T>
Node<T>::Node( int n = 0):number(n)
{}
#7
额,,刚改完,,和你一模一样除了在第二个函数定义时,多个 template<typename T>外,,,但问题还是一样。。
如果去掉那句,,问题更多
#8
你把头文件的名字写出来:然后把头文件里的代码全部贴出来,
然后再把类模板的定义和友元函数的定义所在的文件名字写出来,把源文件的全部代码贴出来
再帮你改
然后再把类模板的定义和友元函数的定义所在的文件名字写出来,把源文件的全部代码贴出来
再帮你改
#9
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
你友元函数中的代码有问题,比如:Node *p = temp.next;都没为指针p分配空间,就使用了,按照我的改,模板格式是没错的
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
你友元函数中的代码有问题,比如:Node *p = temp.next;都没为指针p分配空间,就使用了,按照我的改,模板格式是没错的
#10
好吧,,麻烦了
//typename_Node.h
#ifndef Node_H
#define Node_H
#include<iostream>
using namespace std;
using std::istream;
using std::ostream;
template<typename T>
class Node;
template<typename T>
istream &operator >>( istream &,Node<T> &);
template<typename T>
ostream &operator <<( ostream &,const Node<T> &);
template<typename T>
class Node
{
public:
Node( int =0 );
Node( const Node& );
~Node();
friend istream& operator>> ( istream&, Node<T>& );
friend ostream& operator<< ( ostream&, const Node<T>& );
protected:
Node<T> *next;
T number;
};
template<typename T>
Node<T>::Node( int length )
{
if( length <= 0 )
{
cout << "length wrong ! ";
exit(0);
}
Node* p = next = NULL;
number = 0;
for( int i=1; i<length; i++ )
{
p = new Node;
p->number = 0;
p = p->next;
}
p = NULL;
}
template<typename T>
Node<T>::Node( const Node& mylist )
{
if( mylist.next == NULL )
{
next = '\0';
number = 0;
return ;
}
Node *p1, *p2;
number = mylist.number;
p1 = next;
p2 = mylist.next
while( p2!=NULL )
{
p1->number = p2->number;
p1 = p1->next;
p2 = p2->next;
}
}
template<typename T>
Node<T>::~Node()
{
number = 0;
if( next==NULL )
return;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete p;
}
}
template<typename T>
istream &operator>> <>( istream &input, Node<T> &temp )
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
template<typename T>
ostream &operator<< <>( ostream &output, const Node<T> &temp )
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#endif
#11
我构造函数里的int是要建立链表的长度,,不是里面的数number大小。
我还准备重载[]的,,可以像数组那样使用的,,不过我自己看书太模糊。。。谢啦
#12
上面是你用到的头文件,你的源文件的代码呢,也贴出来,不然的话,头文件的代码修改了,源文件的代码没改,没保持一致也会编译错误的
#13
按照下面的修改,编译是没问题的,也就是语法和格式是正确的,至于功能的实现,要把代码全部贴出来才能知道,不知你用的是什么编译器,我用的是VS2008的编译器。
头文件的代码修改如下:
头文件的代码修改如下:
//typename_Node.h
#ifndef Node_H
#define Node_H
#include <iostream>
using std::ostream;
using std::istream;
using std::cin;
using std::cout;
template<typename T>
class Node;
template<typename T>
istream &operator >>( istream &,Node<T> &);
template<typename T>
ostream &operator <<( ostream &,const Node<T> &);
template<typename T>
class Node
{
public:
Node( int =0 );
Node( const Node<T>& );
~Node();
friend istream& operator>> <>( istream&, Node<T>& );
friend ostream& operator<< <>( ostream&, const Node<T>& );
protected:
Node<T> *next;
T number;
};
template<typename T>
Node<T>::Node( int length = 0 )
{
if( length <= 0 )
{
cout << "length wrong ! ";
exit(0);
}
Node* p = next = NULL;
number = 0;
for( int i=1; i<length; i++ )
{
p = new Node;
p->number = 0;
p = p->next;
}
p = NULL;
}
template<typename T>
Node<T>::Node( const Node<T>& mylist )
{
if( mylist.next == NULL )
{
next = '\0';
number = 0;
return ;
}
Node *p1, *p2;
number = mylist.number;
p1 = next;
p2 = mylist.next
while( p2!=NULL )
{
p1->number = p2->number;
p1 = p1->next;
p2 = p2->next;
}
}
template<typename T>
Node<T>::~Node()
{
number = 0;
if( next==NULL )
return;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete p;
}
}
template<typename T>
istream &operator>> <>( istream &input, Node<T> &temp )
{
Node *p = temp.next;
for( cin>>temp.number; p!=NULL; p=p->next )
cin >> p->number;
return input;
}
template<typename T>
ostream &operator<< <>( ostream &output, const Node<T> &temp )
{
Node *p = next;
for( cout << number; p!=NULL; p=p->next )
cout << " -> " << number;
return output;
}
#endif
#14
感谢啊,,我把一些其他毛病改过后,,差不多了,,但是析构有点问题。。不明白,,感觉很对啊。。
帮忙看下啊
template<typename T>
Node<T>::~Node()
{
number = 0;
for( Node* p = next; p !=NULL; p = next )
{
next = next->next;
delete[] p;
}
}
可以输入输出,,但是最后会有问题。。改为delete p;也不行
如果没有析构,,让计算机析构就没有问题了
我的cpp
//main.cpp
#include<iostream>
#include<ctime>
using namespace std;
#include"myList.h"
int main()
{
Node<int> a(5);
cin >> a;
cout << a;
}
其中#include<ctime>是为以后功能准备的,,可以忽视
再次感谢啊
#15
你想实现的功能是不是建立一个单链表啊?但你的构造函数有问题的,看下面的这个循环;
for( int i=0; i<length; i++ )
{
p = new Node;
p->number = i;
p = p->next;
}
第一个循环是,你的传递的参数length是5,可以执行,但当第二次循环时,执行到P =new Node是,又会调用构造函数,而且使用的默认值,此时length = 0;就会执行exit(0);推出循环,你需要修改构造函数和析构函数
for( int i=0; i<length; i++ )
{
p = new Node;
p->number = i;
p = p->next;
}
第一个循环是,你的传递的参数length是5,可以执行,但当第二次循环时,执行到P =new Node是,又会调用构造函数,而且使用的默认值,此时length = 0;就会执行exit(0);推出循环,你需要修改构造函数和析构函数
#16
不知道到底你的程序想实现什么功能?说具体点,你想干什么
#17
嗯,,就是有这个问题呢。。
我就是想建立一个单链表,,然后会加上其他功能。。
好吧,,已经都麻烦你了,,剩下的我自己搞定吧。。对于类模板中重载输入输出,我已经查到一些资料了。。
太感谢了