天天看点

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,如需转载请自行联系原作者

继续阅读