您的位置:首页 > 编程语言 > C语言/C++

C++模板类的复习记录

2013-05-17 23:48 253 查看
翻出工程,整理总结下。供需要学习的看看就可以了。

# 函数模板

/**
* 函数模板的定义形式:
*
* 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
;
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++程序设计模板类那章内容罢了。

附件:http://down.51cto.com/data/2362859
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息