这两天开始慢慢复习c++基础知识和数据结构的内容了。因为马上各种实习生招聘就开始啦。吼吼。
以前在学c++的时候,没太仔细学模板类,用的时候也很少。我想复习的时候,好好看看。结果,在用模板类实现链表的时候,出问题了。
问题1.编译出错
老规矩,四个文件 node.h,node.cpp, list.h, list.cpp。结果在编译的时候(见makefile文件),总是出问题。查了一下,原因是模板类不能分离编译。于是,只能把类定义和类实现放在同一个文件里。
问题2.全局变量
问题1中,把内容放在同一个文件中,可以了。但是,如果需要在该文件定义了全局变量,怎么办啊?
问题1中,我吧内容都放在了node.cpp 和list.cpp中,因为没有全局变量,所以,include cpp文件不会出神马问题,编译运行都通过。但是,现在如果定义了全局变量,再include cpp文件的话,就会出现多次定义的问题。
如果把node.cpp和node.h中的内容都写到node.h中,又会导致编译不太办。因为编译是基于.cpp的嘛。
解决办法:
1.把 node.cpp中的全局变量声明成static,这是因为static仅在本文件中生效。因此,如果多次include,会多次定义相同的变量,但每个变量的生存范围还是自己的文件。这个方法仅适用于 该变量是常量只读的情况。
2.写一个global.h 文件。把刚才的node.cpp中的问题全部放到这里。只不过,在global.h中,对全局变量仅仅是声明,即需要在每个变量前加extern,然后写一个global.cpp文件,对每个变量进行定义。然后在其他的cpp中 include“global.h文件就好了。问题解决。
基础知识以前就不怎么熟悉,慢慢练习,加深理解。加油。
刚才问了一个同学,说.cpp和.h可以分离编译,显示实例化模板。方法如下:
/* compare.h */
#ifndef __COMPARE_H__
#define __COMPARE_H__
template <class T>
class Compare {
public:
bool operator()(const T& a, const T& b) const;
};
struct Weight {
int weight;
};
#endif
/* compare.cpp */
#include "compare.h"
template <class T>
bool Compare<T>::operator()(const T& a, const T& b) const {
return a < b ? true : false;
}
static bool operator<(const Weight& a, const Weight& b) {
return a.weight < b.weight ? true : false;
}
template class Compare<int>;
template class Compare<double>;
template class Compare<Weight>;
/* main.cpp */
#include <iostream>
#include "compare.h"
using namespace std;
int main() {
cout << Compare<int>()(1, 2) << endl;
cout << Compare<double>()(2.0, 1.0) << endl;
Weight a, b;
a.weight = 1;
b.weight = 2;
cout << Compare<Weight>()(a, b) << endl;
return 0;
}
重要的3行我用红颜色标注了。在分离编译时,如果没有这三句话,会报 undefined reference to ***。原因是根据.h和main.cpp文件 编译器无法实例化模板的实现。有了这三句,编译器就事先实例化这几种类型。然后链接就不会出错了。