什么时候不能使用虚函数

类属static函数,构造函数s,inline函数(请参考《effective c++》p.136),模板成员函数不能virtual,这个比较麻烦,但是它也是由inline造成的,还有一个原因(详见《Think in C++》第二卷第五章),由于存在virtual成员模板函数,我们必须提前知道虚函数表的size大小,这就麻烦了。当然你可以理解为在编译时展开或者是替换的函数与virtual的运行时机制冲突

inline和virtual没关系,表乱讲的说。
加了inline并不代表函数一定要编译期展开,编译器不高兴可以不展;加了virtual不代表函数只能通过虚表间接调用,上下文确定了可以直接调。
inline是一个“建议”,你可以在一些确定没办法inline的函数上加inline修饰,但是编译器会忽略,比如说递归函数肯定没法inline,但是用inline定义的递归函数不是错误。
virtual是告诉编译器为这个函数生成虚表中的入口,但是并不代表调用这个函数必须通过这个入口,如果上下文确定,编译器完全可以跳过虚表直接调用,甚至内联展开,例如:

class A {
public:
    inline virtual void f() {}
};

int main() {
    A a;
    a.f();
}

像样一点的编译器都不会通过虚表调用f(),更像样一点的还会展开inline
准确的说,还有一种成员不能加virtual,那就是成员模板,例如:

class A {
    template
    virtual void f(T t){}
};

这段程序就是错的

你可能感兴趣的:(什么时候不能使用虚函数)