类属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<typename T>
virtual void f(T t){}
};
这段程序就是错的
网友评论