这里,编译main.cpp生成main.o时发现无法找到f到定义,就把它当作外部符号填入外部符号表,等待链接时确定其地址。而f(1); f(10); 通常是对应两条jmp 0x****h指令(当然还有参数的压栈操作),0x****h地址处通常就是一条call f; (C++还会对f进行mangling处理)。这样链接器在链接main.o和test.o时,从test.o到导出符号表(或者内部符号表?)中找到f,得到对应的地址(每个符号对应一个偏移地址),用这个地址替换f,再进行其他的一些必要的重定位,一个可执行文件就形成了。
说了这么多,那么C++模板为什么不能分离式编译呢?
Posts Tagged ‘模板’
November 7, 2009
August 17, 2009
有一点需要注意的是,由于STL内的容器的析构函数都不是virtual的,所以,继承这些容器的类(或者模板类)不能用于多态!这也是不提倡继承STL容器的原因。
不过,由于上面的代码中mstack
继承vector的目的不是使用多态特性,仅仅是复用了vector的接口而已,且复用也仅仅是内部复用;
由于是私有继承,你无法调用父类vector的接口,子类与父类接口并不一致,在语法就不能用于多态;
综上所述,这样的继承并没有什么潜在的危险。
August 16, 2009
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | template <class T> class Queue { public: Queue(int size = 30); ~Queue(); void EnQueue(T value); T DeQueue(); T GetFirst(); bool IsEmpty(); bool IsFull(); void ClearQueue(); private: T *queue; int front; int rare; int MaxSize; int CurLen; }; |
一个堆栈类模板,和用到此模板的一个表达式计算器。
输入四则运算表达式(可含括号),输出计算结果,暂未提供盛放运算和浮点数功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Stack { public: Stack(int stack_size = 30); ~Stack(); void Push(T value); T Pop(); T Top(); bool IsEmpty(); bool IsFull(); void ClearStack(); private: int top; T* stack; int size; }; |
August 14, 2009
1 2 3 4 5 6 7 8 9 10 11 12 | template <class T> T Min(T x, T y) { return x < y ? x : y; } int main() { unsigned ui = 0; int a = Min(ui, 1); return 0; } |
这几行代码又有哪些错误呢?cl.exe提示说,error C2782: ‘T Min(T,T)’ : template parameter ‘T’ is ambiguous。在参数类型的确定上产生了不确定性,这是为什么呢?好吧,1会被解释成是int型的,但是我们平时不是经常把int直接传给unsigned类型的参数吗?可惜的是,此时的Min还不是一个函数,它只是一个模板而已,实例化之前尚不能完成参数的隐式转化(其实,我认为这只是编译器支持与否的问题)。同样,可以用显式特例化的方法来解决:
int a = Min
当然,还可以强制类型转换:
int a = Min(ui, (unsigned)1); 或者 int a = Min(
July 7, 2009
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 | #include <iostream> using namespace std; template <class T> class Base { public: void set(int n){m_data = n;} int get(){return m_data;} private: int static m_data; }; template <class T> int Base<T>::m_data = 0; class Derived1: public Base<Derived1>{}; class Derived2: public Base<Derived2>{}; int main() { Derived1 D1; Derived2 D2; D1.set(1); D2.set(2); cout<<D1.get()<<ends<<D2.get()<<endl;//~ 输出1 2 return 0; } |
其实,这只是一个小把戏,用不同类型实例化后的类完全是两个类型了,当然会拥有不同的静态成员!
June 26, 2009
1 2 3 4 5 6 7 8 9 10 | #include <iostream> #include <iomanip> //~ #include <sqlite.h> //~ #include <mysql/mysql.h> using namespace std; template <unsigned int x, unsigned int y, bool is_ordered = (x >= y)> //~ 一般情况下x>=y struct static_gcd { static int const value = static_gcd<y, x % y>::value; }; |
Page 1 of 11