zoukankan      html  css  js  c++  java
  • 模板类 & 虚函数

     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> .....

    而 c++ 要求在 faux 内存布局一定要在 faux 被实例前就确定(不确定怎么分配内存啊?); 
    但是如果 virtual function 是 template, 以后的使用中可能会有不确定数量的 do<>, 也就是说虚函数表确定不下来, 也就是说 faux 的内存布局确定不下来。
     
    比如 faux 的一个实例:
    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 项。
                          // 这个是不一致的。所以为了避免这些问题, 就要求对象实例化之前虚函数表大小是确定的。
    为什么 vrai 就可以呢?
    由于 vrai 是 template class,他的实例化要等到具体使用时才确定。但是无论哪个实例
    vrai<int> 还是 vrai<string> 他们的虚函数表总是确定的只有一个 virtual do。
  • 相关阅读:
    异步运行
    ES6新增----深入理解generator
    ES6新增(箭头函数)
    ES6新增(有关变量)
    I2C写时序图[转]
    kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
    http://man.linuxde.net/ 转
    Linux网络
    Linux基础:用tcpdump抓包(转)
    指针长度问题,不同架构的指针长度不同,可能32位,也可能64位,与unsigned long长度相同
  • 原文地址:https://www.cnblogs.com/happylong/p/4320794.html
Copyright © 2011-2022 走看看