标签:
1 class faux 2 { 3 public: 4 template <typename T> 5 virtual void do() // member function templates cannot be virtual 6 {} 7 }; 8 9 10 template <typename T> 11 class vrai 12 { 13 public: 14 virtual void do(T v) // ok! 15 {} 16 };
为什么 faux 中不行呢?
因为如果 virtual function 是 template 的, 根据使用的不同类型, class faux 会有很多 do : do<int>,do<string> .....
faux * ff = new faux().
ff->do("hi"); // do<string>, 啊? 虚函数表增加了一项 virtual void do<string> .................. ff->do(9527); // do<int>, 啊? 虚函数表又增加了一项 virtual void do<int> // !! 等等, 不是说 ff 实例化的时候内存布局(包括虚函数表)都要确定下来了吗?调用一个函数添加一个虚函数, 这就违反规则吗。 // 为什么虚函数表一定要确定下来呢?动态添加不是很cool? c++编译器提前 parse 一遍不就好了? // 因为编译器在编译每个 cpp 的时候不管其他 cpp 的,只关心自己的编译单元。不同编译单元之间的引用那是 linker 的事。 // 如果 A.cpp B.cpp 同时包含了 class faux {...}; // 那么编译器编译 A.cpp 的时候增加了几个虚函数表项; 编译器编译 B.cpp 的时候也增加了几个虚函数表项, 那么就会冲突。 // 即便不冲突, 先编译A.cpp 增加了 1,2 项, 接着编译B.cpp 增加 3,4 项, 那么A.obj 看来 faux 的虚函数表只有两项, 而 B.obj 看来 faux 的虚函数表有 4 项。 // 这个是不一致的。所以为了避免这些问题, 就要求对象实例化之前虚函数表大小是确定的。
标签:
原文地址:http://www.cnblogs.com/happylong/p/4320794.html