翻出工程,整理總結下。供需要學習的看看就可以了。
# 函數模板
/** * 函數模板的定義形式: * * template <class T> 或 template <typename T> * 類型名 函數名(參數表) * {函數體的定義} */ template<typename T> T abs(T x) { return x < 0 ? -x : x; } template<class T> void outputArray(const T *P_array, const int count) { for (int i = 0; i < count; i++) cout << P_array[i] << " "; cout << endl; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; const int aCount = 8, bCount = 8, cCount = 20; int aArray[aCount] = {1, 2, 3, 4, 5, 6, 7, 8}; double bArray[bCount] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8}; char cArray[cCount] = "Welcome to see you!"; cout << "a Array contains:" << endl; outputArray(aArray, aCount); cout << "b Array contains:" << endl; outputArray(bArray, bCount); cout << "c Array contains:" << endl; outputArray(cArray, cCount); }
# 類模板
/** * 類模板聲明的語法形式: * * template <模板參數列表> * class 類名 * {類成員聲明} * * 如果需要在類模板外定義其成員函數,則要採用以下的形式: * * template <模板參數列表> * 類型名 類名 <T> :: 函數名(參數表) * * “模板參數列表”由用逗號分隔的若干類型標識符或常量表達式構成,其內容包括: * * 1. class(或typename) 標識符,指明可以接受一個類型參數。 * 2. 類型說明符 標識符,指明可以接受一個由“類型說明符”所規定類型的常量作爲參數。 * * 當“模板參數列表”同時包括上述多項內容時,各項內容以逗號分隔。 * 應該注意的是,模板類的成員函數必須是模板函數。 * * 使用一個模板類來建立對象時,應按如下形式聲明: * * 模板<模板參數類表> 對象名1, ..., 對象名n; */ struct Student { int id; // 學號 float gpa; // 平均分 }; template<class T> class Store { public: Store(void); T GetElem(void); void PutElem(T x); private: T item; int haveValue; }; // 以下實現各成員函數 // 注意:模板類的成員函數,若在類外實現,則必須是模板函數 template<class T> Store<T>::Store(void) : haveValue(0) { } template<class T> T Store<T>::GetElem(void) { if (haveValue == 0) { cout << "No item present!" << endl; exit(1); // 退出 } return item; } template<class T> void Store<T>::PutElem(T x) { haveValue++; item = x; } int main() { Student g = {1000, 23}; Store<int> S1, S2; Store<Student> S3; Store<double> D; S1.PutElem(3); S2.PutElem(-7); cout << S1.GetElem() << " " << S2.GetElem() << endl; S3.PutElem(g); cout << "The student is " << S3.GetElem().id << endl; cout << "Retrieving object D "; cout << D.GetElem() << endl; // D未設值,D.GetElem()時會終止。 }
# 模板類不能分離編譯
/** * 注意:模板類不能分離編譯(除非實現export的編譯器) * @see <a href="http://stackoverflow.com/questions/10632251/undefined-reference-to-template-function">undefined reference</a> */
也就需要在頭文件裏實現。
我們可以在定義模板類的xxx.h末尾#include "xxx_impl.h",而後在xxx_impl.h裏實現。
# 模板函數指針
/** * C++模板函數指針:http://www.cnblogs.com/easyfrog/archive/2012/11/04/2753468.html * 注意:struct封裝後的函數,再用在模板函數上不成。 */ template<class T> struct Wrapper { typedef void (*funcPtr)(T*, int); };
或者,直接放到模板函數參數裏:
template<class T> void timeit(void (*funcPtr)(T*, int), T A[], int n) { clock_t stamp_start, stamp_end; stamp_start = clock(); funcPtr(A, n); // 執行函數 stamp_end = clock(); double duration = (double) (stamp_end - stamp_start) / CLOCKS_PER_SEC; cout << "Cost: " << duration << " secs." << endl; }
# 附加產物
## 均勻隨機排列數組,以便測試排序算法
void swap(int *a, int *b) { int t; t = *a; *a = *b; *b = t; } // 均勻隨機排列[0,n-1] int* rand_ints(const int n) { srand((unsigned) time(0)); // 隨機種子 int *a = new int[n]; int i; for (i = 0; i < n; ++i) { a[i] = i; } for (i = n; i > 1; --i) { // swap A[i-1] & A[RANDOM(0, i-1)] swap(&a[i - 1], &a[rand() % i]); } return a; }
## 多工程目錄的makefie配置方法
makefile:(主makefile)
DIRS是子目錄,這裏列全吧。以大概說明下工程裏的內容。
DIRS = \ temp_func \ temp_cls \ temp_array \ temp_list \ temp_stack \ temp_queue \ temp_sort \ temp_search all: @for dir in $(DIRS) ; do \ if test -d $$dir ; then \ echo "$$dir: $(MAKE) $@" ; \ if (cd $$dir; $(MAKE) $@) ; then \ true; \ else \ exit 1; \ fi; \ fi \ done clean: @for dir in $(DIRS) ; do \ if test -d $$dir ; then \ echo "$$dir: $(MAKE) $@" ; \ if (cd $$dir; $(MAKE) $@) ; then \ true; \ else \ exit 1; \ fi; \ fi \ done
然後準備一個頭一個尾:
makefile.init:(一些基本變量)
CXXFLAGS = -O0 -g3 -Wall -c -fmessage-length=0 MD := mkdir -p RM := rm -rf OUT_DIR := debug
makefile.targets:(通用的編譯target)
all: $(TARGET) $(TARGET): $(OBJS) @echo ' ' @echo 'Building target: $@' $(CXX) -o "$(TARGET)" $(OBJS) $(LIBS) @echo 'Finished building target: $@' @echo ' ' $(OUT_DIR)/%.o: %.cpp @echo ' ' @echo 'Building file: $<' $(MD) $(OUT_DIR) $(CXX) $(CXXFLAGS) -o "$@" "$<" @echo 'Finished building: $<' clean: $(RM) $(OBJS) $(TARGET)
繼而,子目錄下makefile只需要這樣:
-include ../makefile.init SRCS := main.cpp OBJS := $(OUT_DIR)/main.o LIBS := TARGET := $(OUT_DIR)/temp_sort.exe -include ../makefile.targets
記得把子目錄加進主makefile的DIRS裏就好了。
# 附件工程
其實就C++程序設計模板類那章內容罷了。