类模板和虚函数

class templates and virtual functions

本文关键字:函数      更新时间:2023-10-16

给出下面的代码,为什么编译器抛出一个错误(说方法calc()不是Model2的成员)当使用Sub<Model2>实例时,如果fn()被声明为虚拟的,并且当fn()不是虚拟的时候工作?发生了什么事?

class Model1
{
public:
    void calc(){std::cout<<"Model1 calc"<<std::endl;}
};
class Model2
{
public:
    void calc2(){std::cout<<"Model2 calc"<<std::endl;}
};
template<typename T>
class Super : public T
{
public:
    virtual void fn() // comment virtual for resolution
    { T::calc(); }
};
template<typename T>
class Sub : public Super<T>
{
public:
    void fn()
    { T::calc2(); }
};
int main()
{
    Super<Model1> bes;
    bes.fn();
    Sub<Model2> sts1;
    sts1.fn();
    return 0;
}

虚方法必须在模板中实例化,而非虚方法则不必。

错误取决于T的"需求"发生在实例化的时刻。
非虚方法仅在使用或显式实例化时才实例化。

在你的例子中,当不是虚拟时,Super<Model2>::fn永远不会被调用(它是Sub<Model2>::fn)。
在虚拟的情况下,Super<Model2>::fn不被调用,但是必须被实例化,因为它是虚拟的。