模板必须在使用它的时候才实例化,因此模板不能单独编译。如果把模板声明放在.h文件,把模板函数的定义放在.cpp里。在
使用到模板的地方,由于只include了头文件,当然就找不到函数定义的代码。因此,简单的办法就是把模板函数的定义和声明都
放在.h头文件里。
但是这就出现了一个问题。a.cpp使用了模板,因此就定义了一个该模板类型的实例。如果b.cpp也使用了与a.cpp相同的模板
实例,则编译器又在b.o定义了一个相同的模板实例。这样在最终的可执行程式或库中有重复的模板实例。
为了解决这个问题,可以在编译和链接的时候 加上 -qtempinc选项。编译期在遇到这个选项时,会将模板的实例化代码放在
一个临时目录:tempinc下。后续编译其它文件时,如果使用了相同的模板实例,将不再对它进行实例化。然后,在链接期,再
将tempinc下的实例化代码写进最终的目标文件。这样就起到防止最终的可执行程式或库中有重复的模板实例的效果。
当然,使用tempinc需要按一次的步骤:
1. Declare your class templates and function templates in template header files, with a .h extension.
2. For each template declaration file, create a template implementation file. This file must have the same file name as the template declaration file and an extension of .c or .t, or the name must be specified in a #pragma implementation directive. For a class template, the implementation file defines the member functions and static data members. For a function template, the implementation file defines the function.
3. In your source program, specify an #include directive for each template declaration file.
4. Optionally, to ensure that your code is applicable for both -qtempinc and -qnotempinc compilations, in each template declaration file, conditionally include the corresponding template implementation file if the __TEMPINC__ macro is not defined. (This macro is automatically defined when you use the -qtempinc compilation option.)
This produces the following results:
o Whenever you compile with -qnotempinc, the template implementation file is included.
o Whenever you compile with -qtempinc, the compiler does not include the template implementation file. Instead, the compiler looks for a file with the same name as the template implementation file and extension .c the first time it needs a particular instantiation. If the compiler subsequently needs the same instantiation, it uses the copy stored in the template include directory.
例子:
Template declaration file: stack.h
This header file defines the class template for the class Stack.
#ifndef STACK_H
#define STACK_H
template <class Item, int size> class Stack {
public:
void push(Item item); // Push operator
Item pop(); // Pop operator
int isEmpty(){
return (top==0); // Returns true if empty, otherwise false
}
Stack() { top = 0; } // Constructor defined inline
private:
Item stack[size]; // The stack of items
int top; // Index to top of stack
};
#ifndef __TEMPINC__ // 3
#include "stack.c" // 3
#endif // 3
#endif
Template implementation file: stack.c
This file provides the implementation of the class template for the class Stack.
template <class Item, int size>
void Stack<Item,size>::push(Item item) {
if (top >= size) throw size;
stack[top++] = item;
}
template <class Item, int size>
Item Stack<Item,size>::pop() {
if (top <= 0) throw size;
Item item = stack[--top];
return(item);
}
Function declaration file: stackops.h
This header file contains the prototype for the add function, which is used in both stackadd.cpp and stackops.cpp.
void add(Stack<int, 50>& s);
Function implementation file: stackops.cpp
This file provides the implementation of the add function, which is called from the main program.
#include "stack.h" // 1
#include "stackops.h" // 2
void add(Stack<int, 50>& s) {
int tot = s.pop() + s.pop();
s.push(tot);
return;
}
Main program file: stackadd.cpp
This file creates a Stack object.
#include <iostream.h>
#include "stack.h" // 1
#include "stackops.h" // 2
main() {
Stack<int, 50> s; // create a stack of ints
int left=10, right=20;
int sum;
s.push(left); // push 10 on the stack
s.push(right); // push 20 on the stack
add(s); // pop the 2 numbers off the stack
// and push the sum onto the stack
sum = s.pop(); // pop the sum off the stack
cout << "The sum of: " << left << " and: " << right << " is: " << sum << endl;
return(0);
}