仍是鄧俊輝老師數據結構中List那一章的例子。
List的遍歷問題。windows
main.cpp裏調用
PRINT ( La ); // La是一個自定義的List對象
數據結構
PRINT這個宏的定義就在main.cpp裏
#define PRINT(x) { print(x); crc(x); checkOrder(x); }
函數
print的聲明在UniPrint/print.h裏指針
template <typename T> static void print ( T& x ) { UniPrint::p ( x ); } #include "print_implementation.h"
注意C++模板類的定義和實現必需要在同一個文件中,一般是頭文件,由於編譯器要看到模板實現才能展開模板。
可是print.h裏的模板類UniPrint只有方法的聲明,沒有方法的實現。
因此print.h的末尾引入了print_implementation.h這個頭文件。UniPrint::p的實現就在這個頭文件裏。
這也是C++模板類的經常使用寫法。code
print_implementation.h裏又引入了Print_traversable.h,UniPrint::p的真正實如今Print_traversable.h裏。(windows上C++頭文件不分大小寫)對象
print_traversable.h編譯器
template <typename T> //元素類型 void UniPrint::p ( T& s ) { //引用 printf ( "%s[%d]*%d:\n", typeid ( s ).name(), &s, s.size() ); //基本信息 s.traverse ( print ); //經過print()遍歷輸出全部元素 printf ( "\n" ); }
運行到s.traverse( print );
這一句的時候會跳到traverse方法裏去。it
list.hio
template <typename T> void List<T>::traverse ( void ( *visit ) ( T& ) )//藉助函數指針機制遍歷 { for (ListNodePosi(T) p = header->succ; p != trailer; p = p->succ) { printf("%s", "sss"); visit(p->data); } // 由於T已經被替換成了int。因此這裏的visit實際上是UnitPrint::p的模板實例,在print_basic.cpp裏 }
從traverse方法來看,它接收的是一個函數指針,這個函數接收一個T型引用的參數,且沒返回值。
因此s.traverse ( print );中print方法也應該接收一個T型引用的參數。
縱觀print.h中只有這一句符合條件:template <typename T> static void print ( T& x ) { UniPrint::p ( x ); }
編譯
咦?不對呀,這怎麼又回來了?怕不是死循環?