天天看點

C++模闆類的複習記錄

翻出工程,整理總結下。供需要學習的看看就可以了。

# 函數模闆

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<code>/**</code>

<code> </code><code>* 函數模闆的定義形式:</code>

<code> </code><code>*</code>

<code> </code><code>* template &lt;class T&gt; 或 template &lt;typename T&gt;</code>

<code> </code><code>* 類型名 函數名(參數表)</code>

<code> </code><code>* {函數體的定義}</code>

<code> </code><code>*/</code>

<code>template</code><code>&lt;</code><code>typename</code> <code>T&gt;</code>

<code>T </code><code>abs</code><code>(T x)</code>

<code>{</code>

<code>    </code><code>return</code> <code>x &lt; 0 ? -x : x;</code>

<code>}</code>

<code>template</code><code>&lt;</code><code>class</code> <code>T&gt;</code>

<code>void</code> <code>outputArray(</code><code>const</code> <code>T *P_array, </code><code>const</code> <code>int</code> <code>count)</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i = 0; i &lt; count; i++)</code>

<code>        </code><code>cout &lt;&lt; P_array[i] &lt;&lt; </code><code>" "</code><code>;</code>

<code>    </code><code>cout &lt;&lt; endl;</code>

<code>int</code> <code>main()</code>

<code>    </code><code>int</code> <code>n = -5;</code>

<code>    </code><code>double</code> <code>d = -5.5;</code>

<code>    </code><code>cout &lt;&lt; </code><code>abs</code><code>(n) &lt;&lt; endl;</code>

<code>    </code><code>cout &lt;&lt; </code><code>abs</code><code>(d) &lt;&lt; endl;</code>

<code>    </code><code>const</code> <code>int</code> <code>aCount = 8, bCount = 8, cCount = 20;</code>

<code>    </code><code>int</code> <code>aArray[aCount] = {1, 2, 3, 4, 5, 6, 7, 8};</code>

<code>    </code><code>double</code> <code>bArray[bCount] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8};</code>

<code>    </code><code>char</code> <code>cArray[cCount] = </code><code>"Welcome to see you!"</code><code>;</code>

<code>    </code><code>cout &lt;&lt; </code><code>"a Array contains:"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>outputArray(aArray, aCount);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"b Array contains:"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>outputArray(bArray, bCount);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"c Array contains:"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>outputArray(cArray, cCount);</code>

# 類模闆

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

<code> </code><code>* 類模闆聲明的文法形式:</code>

<code> </code><code>* template &lt;模闆參數清單&gt;</code>

<code> </code><code>* class 類名</code>

<code> </code><code>* {類成員聲明}</code>

<code> </code><code>* 如果需要在類模闆外定義其成員函數,則要采用以下的形式:</code>

<code> </code><code>* 類型名 類名 &lt;T&gt; :: 函數名(參數表)</code>

<code> </code><code>* “模闆參數清單”由用逗号分隔的若幹類型辨別符或常量表達式構成,其内容包括:</code>

<code> </code><code>* 1. class(或typename) 辨別符,指明可以接受一個類型參數。</code>

<code> </code><code>* 2. 類型說明符 辨別符,指明可以接受一個由“類型說明符”所規定類型的常量作為參數。</code>

<code> </code><code>* 當“模闆參數清單”同時包括上述多項内容時,各項内容以逗号分隔。</code>

<code> </code><code>* 應該注意的是,模闆類的成員函數必須是模闆函數。</code>

<code> </code><code>* 使用一個模闆類來建立對象時,應按如下形式聲明:</code>

<code> </code><code>* 模闆&lt;模闆參數類表&gt; 對象名1, ..., 對象名n;</code>

<code>struct</code> <code>Student {</code>

<code>    </code><code>int</code> <code>id; </code><code>// 學号</code>

<code>    </code><code>float</code> <code>gpa; </code><code>// 平均分</code>

<code>};</code>

<code>class</code> <code>Store {</code>

<code>public</code><code>:</code>

<code>    </code><code>Store(</code><code>void</code><code>);</code>

<code>    </code><code>T GetElem(</code><code>void</code><code>);</code>

<code>    </code><code>void</code> <code>PutElem(T x);</code>

<code>private</code><code>:</code>

<code>    </code><code>T item;</code>

<code>    </code><code>int</code> <code>haveValue;</code>

<code>// 以下實作各成員函數</code>

<code>// 注意:模闆類的成員函數,若在類外實作,則必須是模闆函數</code>

<code>Store&lt;T&gt;::Store(</code><code>void</code><code>)</code>

<code>    </code><code>: haveValue(0)</code>

<code>T Store&lt;T&gt;::GetElem(</code><code>void</code><code>)</code>

<code>    </code><code>if</code> <code>(haveValue == 0) {</code>

<code>        </code><code>cout &lt;&lt; </code><code>"No item present!"</code> <code>&lt;&lt; endl;</code>

<code>        </code><code>exit</code><code>(1); </code><code>// 退出</code>

<code>    </code><code>}</code>

<code>    </code><code>return</code> <code>item;</code>

<code>void</code> <code>Store&lt;T&gt;::PutElem(T x)</code>

<code>    </code><code>haveValue++;</code>

<code>    </code><code>item = x;</code>

<code>    </code><code>Student g = {1000, 23};</code>

<code>    </code><code>Store&lt;</code><code>int</code><code>&gt; S1, S2;</code>

<code>    </code><code>Store&lt;Student&gt; S3;</code>

<code>    </code><code>Store&lt;</code><code>double</code><code>&gt; D;</code>

<code>    </code><code>S1.PutElem(3);</code>

<code>    </code><code>S2.PutElem(-7);</code>

<code>    </code><code>cout &lt;&lt; S1.GetElem() &lt;&lt; </code><code>" "</code> <code>&lt;&lt; S2.GetElem() &lt;&lt; endl;</code>

<code>    </code><code>S3.PutElem(g);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"The student is "</code> <code>&lt;&lt; S3.GetElem().id &lt;&lt; endl;</code>

<code>    </code><code>cout &lt;&lt; </code><code>"Retrieving object D "</code><code>;</code>

<code>    </code><code>cout &lt;&lt; D.GetElem() &lt;&lt; endl; </code><code>// D未設值,D.GetElem()時會終止。</code>

# 模闆類不能分離編譯

<code> </code><code>* 注意:模闆類不能分離編譯(除非實作export的編譯器)</code>

<code> </code><code>* @see &lt;a href="http://stackoverflow.com/questions/10632251/undefined-reference-to-template-function"&gt;undefined reference&lt;/a&gt;</code>

也就需要在頭檔案裡實作。

我們可以在定義模闆類的xxx.h末尾#include "xxx_impl.h",而後在xxx_impl.h裡實作。

# 模闆函數指針

<code> </code><code>* C++模闆函數指針:http://www.cnblogs.com/easyfrog/archive/2012/11/04/2753468.html</code>

<code> </code><code>* 注意:struct封裝後的函數,再用在模闆函數上不成。</code>

<code>struct</code> <code>Wrapper {</code>

<code>    </code><code>typedef</code> <code>void</code> <code>(*funcPtr)(T*, </code><code>int</code><code>);</code>

或者,直接放到模闆函數參數裡:

<code>void</code> <code>timeit(</code><code>void</code> <code>(*funcPtr)(T*, </code><code>int</code><code>), T A[], </code><code>int</code> <code>n) {</code>

<code>    </code><code>clock_t</code> <code>stamp_start, stamp_end;</code>

<code>    </code><code>stamp_start = </code><code>clock</code><code>();</code>

<code>    </code><code>funcPtr(A, n); </code><code>// 執行函數</code>

<code>    </code><code>stamp_end = </code><code>clock</code><code>();</code>

<code>    </code><code>double</code> <code>duration = (</code><code>double</code><code>) (stamp_end - stamp_start) / CLOCKS_PER_SEC;</code>

<code>    </code><code>cout &lt;&lt; </code><code>"Cost: "</code> <code>&lt;&lt; duration &lt;&lt; </code><code>" secs."</code> <code>&lt;&lt; endl;</code>

# 附加産物

## 均勻随機排列數組,以便測試排序算法

<code>void</code> <code>swap(</code><code>int</code> <code>*a, </code><code>int</code> <code>*b)</code>

<code>    </code><code>int</code> <code>t;</code>

<code>    </code><code>t = *a;</code>

<code>    </code><code>*a = *b;</code>

<code>    </code><code>*b = t;</code>

<code>// 均勻随機排列[0,n-1]</code>

<code>int</code><code>* rand_ints(</code><code>const</code> <code>int</code> <code>n)</code>

<code>    </code><code>srand</code><code>((unsigned) </code><code>time</code><code>(0)); </code><code>// 随機種子</code>

<code>    </code><code>int</code> <code>*a = </code><code>new</code> <code>int</code><code>[n];</code>

<code>    </code><code>int</code> <code>i;</code>

<code>    </code><code>for</code> <code>(i = 0; i &lt; n; ++i) {</code>

<code>        </code><code>a[i] = i;</code>

<code>    </code><code>for</code> <code>(i = n; i &gt; 1; --i) {</code>

<code>        </code><code>// swap A[i-1] &amp; A[RANDOM(0, i-1)]</code>

<code>        </code><code>swap(&amp;a[i - 1], &amp;a[</code><code>rand</code><code>() % i]);</code>

<code>    </code><code>return</code> <code>a;</code>

## 多工程目錄的makefie配置方法

makefile:(主makefile)

DIRS是子目錄,這裡列全吧。以大概說明下工程裡的内容。

<code>DIRS = \</code>

<code>    </code><code>temp_func \</code>

<code>    </code><code>temp_cls \</code>

<code>    </code><code>temp_array \</code>

<code>    </code><code>temp_list \</code>

<code>    </code><code>temp_stack \</code>

<code>    </code><code>temp_queue \</code>

<code>    </code><code>temp_sort \</code>

<code>    </code><code>temp_search</code>

<code>all:</code>

<code>    </code><code>@for dir in $(DIRS) ; do \</code>

<code>        </code><code>if test -d $$dir ; then \</code>

<code>            </code><code>echo "$$dir: $(MAKE) $@" ; \</code>

<code>            </code><code>if (cd $$dir; $(MAKE) $@) ; then \</code>

<code>                </code><code>true; \</code>

<code>            </code><code>else \</code>

<code>                </code><code>exit 1; \</code>

<code>            </code><code>fi; \</code>

<code>        </code><code>fi \</code>

<code>    </code><code>done</code>

<code>clean:</code>

然後準備一個頭一個尾:

makefile.init:(一些基本變量)

<code>CXXFLAGS = -O0 -g3 -Wall -c -fmessage-length=0</code>

<code>MD := mkdir -p</code>

<code>RM := rm -rf</code>

<code>OUT_DIR := debug</code>

makefile.targets:(通用的編譯target)

<code>all: $(TARGET)</code>

<code>$(TARGET): $(OBJS)</code>

<code>    </code><code>@echo ' '</code>

<code>    </code><code>@echo 'Building target: $@'</code>

<code>    </code><code>$(CXX) -o "$(TARGET)" $(OBJS) $(LIBS)</code>

<code>    </code><code>@echo 'Finished building target: $@'</code>

<code>$(OUT_DIR)/%.o: %.cpp</code>

<code>    </code><code>@echo 'Building file: $&lt;'</code>

<code>    </code><code>$(MD) $(OUT_DIR)</code>

<code>    </code><code>$(CXX) $(CXXFLAGS) -o "$@" "$&lt;"</code>

<code>    </code><code>@echo 'Finished building: $&lt;'</code>

<code>    </code><code>$(RM) $(OBJS) $(TARGET)</code>

繼而,子目錄下makefile隻需要這樣:

<code>-include ../makefile.init</code>

<code>SRCS := main.cpp</code>

<code>OBJS := $(OUT_DIR)/main.o</code>

<code>LIBS :=</code>

<code>TARGET := $(OUT_DIR)/temp_sort.exe</code>

<code>-include ../makefile.targets</code>

記得把子目錄加進主makefile的DIRS裡就好了。

# 附件工程

其實就C++程式設計模闆類那章内容罷了。

<a href="http://down.51cto.com/data/2362859" target="_blank">附件:http://down.51cto.com/data/2362859</a>

     本文轉自winorlose2000 51CTO部落格,原文連結:http://blog.51cto.com/vaero/1202995,如需轉載請自行聯系原作者

繼續閱讀