[关闭]
@Xc-liu 2018-08-31T23:26:12.000000Z 字数 5794 阅读 758

关于模版类中重载友元函数的问题

c++ 数据结构(图)


问题描述:

  • 代码主体
  1. Graph.h
  2. Graphmtx.h
  3. g_mtx_test.cpp
  4. g_mtx.txt
  • 完整代码
  1. Graph.h
  1. #ifndef GRAPH_H_
  2. #define GRAPH_H_
  3. #include <climits>
  4. const int DefaultVertices=30;
  5. template<typename T,typename E>
  6. class Graph{
  7. public:
  8. const E maxWeight=INT_MAX;
  9. Graph(int sz=DefaultVertices);
  10. ~Graph();
  11. bool GraphEmpty()const{
  12. if(numEdges==0){return true;}
  13. else{return false;}
  14. }
  15. bool GraphFull()const{
  16. if(numVertices==maxVertices||numEdges==maxVertices*(maxVertices-1)/2){
  17. return true;
  18. }else{
  19. return false;
  20. }
  21. }
  22. int NumberOfVertices(){return numVertices;}
  23. int NumberOfEDges(){return numEdges;}
  24. virtual T getValue(int i);
  25. virtual E getWeight(int v1,int v2);
  26. virtual int getFirstNeighbor(int v);
  27. virtual int getNextNeighbor(int v,int w);
  28. virtual bool insertVertex(const T& vertex);
  29. virtual bool insertEdge(int v1,int v2,E const);
  30. virtual bool removeVertex(int v);
  31. virtual bool removeEdge(int v1,int v2);
  32. protected:
  33. int maxVertices;
  34. int numEdges;
  35. int numVertices;
  36. virtual int getVertexPos(T vertex);
  37. };
  38. #endif
  1. Graphmtx.h
  1. #ifndef GRAPHMTX_H_
  2. #define GRAPHMTX_H_
  3. #include <iostream>
  4. #include <fstream>
  5. #include <stdlib.h>
  6. #include "Graph.h"
  7. using namespace std;
  8. extern const int DefaultVertices;
  9. template<typename T,typename E>
  10. class Graphmtx:public Graph<T,E>{
  11. public:
  12. Graphmtx(int size=DefaultVertices);
  13. Graphmtx(char *filename,int size=DefaultVertices);
  14. ~Graphmtx(){delete []VerticesList;delete []Edge;}
  15. T getValue(int i){
  16. return i>=0&&i<=this->numVertices?VerticesList[i]:NULL;
  17. }
  18. E getWeight(int v1,int v2){
  19. return v1!=-1&&v2!=-1?Edge[v1][v2]:0;
  20. }
  21. int getFirstNeighbor(int v);
  22. int getNextNeighbor(int v,int w);
  23. bool insertVertex(const T& vertex);
  24. bool insertEdge(int v1,int v2,E cost);
  25. bool removeVertex(int v);
  26. bool removeEdge(int v1,int v2);
  27. friend ostream& operator << <T,E>(ostream& out,Graphmtx<T,E>& G);
  28. private:
  29. T *VerticesList;
  30. E **Edge;
  31. int getVertexPos(T vertex){
  32. for(int i=0;i<this->numVertices;i++){
  33. if(VerticesList[i]==vertex){return i;}
  34. return -1;
  35. }
  36. }
  37. };
  38. template<typename T,typename E>
  39. Graphmtx<T,E>::Graphmtx(int size){
  40. cout << "fuck" <<endl;
  41. this->maxVertices=size;this->numVertices=0;this->numEdges=0;
  42. int i,j;
  43. VerticesList=new T[this->maxVertices];
  44. Edge=(E **)new E*[this->maxVertices];
  45. for(i=0;i<this->maxVertices;i++){
  46. Edge[i]=new E[this->maxVertices];
  47. }
  48. for(j=0;j<this->maxVertices;j++){
  49. for(i=0;i<this->maxVertices;i++){
  50. Edge[i][j]=(i==j)?0:this->maxWeight;
  51. }
  52. }
  53. }
  54. template<typename T,typename E>
  55. Graphmtx<T,E>::Graphmtx(char *filename,int size){
  56. Graphmtx( );
  57. ifstream inFile;
  58. inFile.open(filename);
  59. if(!inFile.is_open()){
  60. cout<<"Couldn't open the file: "<<filename <<endl;
  61. exit(EXIT_FAILURE);
  62. }
  63. T v_value;E w_value;
  64. inFile >> v_value;
  65. insertVertex(v_value);
  66. while(v_value!=';'&&!inFile.eof()){
  67. inFile>>v_value;
  68. if(v_value!=','){
  69. insertVertex(v_value);
  70. }
  71. }
  72. int j,k;
  73. while(!inFile.eof()){
  74. for(int i=0;i<6;i++){
  75. if(i<4){
  76. inFile >> v_value;
  77. if(i==0&&v_value!=','){j=getVertexPos(v_value);}
  78. if(i==2&&v_value!=','){k=getVertexPos(v_value);}
  79. }else if(i==4){
  80. inFile >> w_value;
  81. if(j==-1||k==-1){
  82. cout << "input error!" <<endl;
  83. }else{
  84. insertEdge(j,k,w_value);
  85. }
  86. }else if(i==5){
  87. char temp;
  88. inFile >>temp;
  89. if(temp!=';'){
  90. cout << "input error!"<< endl;
  91. }
  92. }
  93. }
  94. }
  95. }
  96. template<typename T,typename E>
  97. int Graphmtx<T,E>::getFirstNeighbor(int v){
  98. if(v!=-1){
  99. for(int col=0;col<this->numVertices;col++){
  100. if(Edge[v][col]>0&&Edge[v][col]<this->maxWeight){
  101. return col;
  102. }
  103. }
  104. }else{return -1;}
  105. }
  106. template<typename T,typename E>
  107. int Graphmtx<T,E>::getNextNeighbor(int v,int w){
  108. if(v!=-1&&w!=-1){
  109. for(int col=w+1;col<this->numVertices;col++){
  110. if(Edge[v][col]>0&&Edge[v][col]<this->maxWeight){
  111. return col;
  112. }
  113. }
  114. }else{return -1;}
  115. }
  116. template<typename T,typename E>
  117. bool Graphmtx<T,E>::insertVertex(const T& vertex){
  118. if(this->numVertices==this->maxVertices){return false;}
  119. VerticesList[this->numVertices++]=vertex;
  120. return true;
  121. }
  122. template<typename T,typename E>
  123. bool Graphmtx<T,E>::removeVertex(int v){
  124. if(v<0||v>=this->numVertices){return false;}
  125. if(this->numVertices==1){return false;}
  126. int i,j;
  127. VerticesList[v]=VerticesList[this->numVertices-1];
  128. for(i=0;i<this->numVertices;i++){
  129. if(Edge[i][v]>0&&Edge[i][v]<this->maxWeight){this->numEdges--;}
  130. }
  131. for(i=0;i<this->numVertices;i++){
  132. Edge[i][v]=Edge[i][this->numVertices-1];
  133. }
  134. for(j=0;j<this->numVertices;j++){
  135. Edge[v][j]=Edge[this->numVertices-1][j];
  136. }
  137. this->numVertices--;
  138. return true;
  139. }
  140. template<typename T,typename E>
  141. bool Graphmtx<T,E>::insertEdge(int v1,int v2,E cost){
  142. if(v1>-1&&v1<this->numVertices&&v2>-1&&v2<this->numVertices
  143. &&Edge[v1][v2]==this->maxWeight){
  144. Edge[v1][v2]=Edge[v2][v1]=cost;
  145. this->numEdges++;
  146. return true;
  147. }else{
  148. return false;
  149. }
  150. }
  151. template<typename T,typename E>
  152. bool Graphmtx<T,E>::removeEdge(int v1,int v2){
  153. if(v1>-1&&v1<this->numVertices&&v2>-1&&v2<this->numVertices
  154. &&Edge[v1][v2]>0&&Edge[v1][v2]<this->maxWeight){
  155. Edge[v1][v2]=Edge[v2][v1]=this->maxWeight;
  156. this->numEdges--;
  157. return true;
  158. }else{
  159. return false;
  160. }
  161. }
  162. template<typename T,typename E>
  163. ostream& operator <<(ostream& out,Graphmtx<T,E>& G){
  164. int i,j,n,m;T e1,e2;E w;
  165. n=G.NumberOfVertices();m=G.NumberOfEDges;
  166. out<< n << ","<<m<<endl;
  167. for(i=0;i<n;i++){
  168. for(j=i+1;j<n;j++){
  169. w=G.getWeight(i,j);
  170. if(w>0 &&w<Graph<T,E>::maxWeight){
  171. e1=G.getValue(i);e2=G.getValue(j);
  172. out << "(" << e1 << ","<<e2 <<":" << w << ")"<<endl;
  173. }
  174. }
  175. }
  176. return out;
  177. }
  178. #endif

3.g_mtx_test.cpp

  1. #include "Graphmtx.h"
  2. #include <iostream>
  3. using namespace std;
  4. int main(){
  5. /*char* filename=new char[30];
  6. cout << "please input the filename (less than 30 signals) " << endl;
  7. cin.getline(filename,30); */
  8. Graphmtx<char,int> g_mtx(filename);
  9. //cout << g_mtx <<endl;
  10. return 0;
  11. }

4.g_mtx.txt

  1. A,B,C,D,E;
  2. A,B,24;A,C,46;B,C,15;B,E,67;C,B,37;C,D,53;E,D,31;
  1. makefile
  1. CC = g++
  2. CFLAGS = -Wall -O2 -std=c++11 #-I../../common_library/# 指定头文件首先搜索的路径
  3. Filename=g_mtx_test
  4. End=.cpp
  5. $(Filename): $(Filename)$(End) #../../common_library/mystd.cpp
  6. @$(CC) $(CFLAGS) -o $@ $^ #-I ../../DataStructureHomework/chapter2
  • 报错形式

编译器显示在链接的过程中出错。

编译结果图

解决方法:

问题在于重载友元函数出错。下面给出目前为止发现能够正确编译的一种重载友元函数的方式:

  1. ......
  2. template<typename T>
  3. class class_name;
  4. tempalate<typename T>
  5. ostream& operator << (ostream& out,class_name<T> class_instance);
  6. ......
  7. tempalate<typename T>
  8. class class_name(){
  9. ......
  10. friend ostream& operator << <T> (ostream& out,class_name<T> class_instance)//注意这里的区别
  11. ......
  12. }
  13. //重载友元函数的具体实现
  14. tempalate<typename T>
  15. ostream& operator << (ostream& out,class_name<T> class_instance){
  16. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注