1.编译过程
hello.cpp程序是高级c语言程序,这种程序易于被人读懂。为了在系统上运行hello.c程序,每一条c语句都必须转化为低级的机器指令。然后将这些机器指令打包成可执行目标文件格式,并以二进制形式存储于磁盘中。
预处理(Pre-processing) -> 编译(Compiling) ->汇编(Assembling) -> 链接(Linking)
2. 模板实现机制
函数模板机制结论:
- 编译器并不是把函数模板处理成能够处理任何类型的函数
- 函数模板通过具体类型产生不同的函数
- 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。
3. 模板的局限性
假设有如下模板函数:
template<class T>
void f(T a, T b)
{ … }
如果代码实现时定义了赋值操作 a = b,但是T为数组,这种假设就不成立了
同样,如果里面的语句为判断语句 if(a>b),但T如果是结构体,该假设也不成立,另外如果是传入的数组,数组名为地址,因此它比较的是地址,而这也不是我们所希望的操作。
总之,编写的模板函数很可能无法处理某些类型,另一方面,有时候通用化是有意义的,但C++语法不允许这样做。为了解决这种问题,可以提供模板的重载,为这些特定的类型提供具体化的模板。
class Person
{
public:
Person(string name, int age)
{
this->mName = name;
this->mAge = age;
}
string mName;
int mAge;
};
//普通交换函数
template <class T>
void mySwap(T &a,T &b)
{
T temp = a;
a = b;
b = temp;
}
//第三代具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<>void mySwap<Person>(Person &p1, Person &p2)
{
string nameTemp;
int ageTemp;
nameTemp = p1.mName;
p1.mName = p2.mName;
p2.mName = nameTemp;
ageTemp = p1.mAge;
p1.mAge = p2.mAge;
p2.mAge = ageTemp;
}
void test()
{
Person P1("Tom", 10);
Person P2("Jerry", 20);
cout << "P1 Name = " << P1.mName << " P1 Age = " << P1.mAge << endl;
cout << "P2 Name = " << P2.mName << " P2 Age = " << P2.mAge << endl;
mySwap(P1, P2);
cout << "P1 Name = " << P1.mName << " P1 Age = " << P1.mAge << endl;
cout << "P2 Name = " << P2.mName << " P2 Age = " << P2.mAge << endl;
}