转-C++之虚函数不能定义成内联函数的原因

转自:https://blog.csdn.net/flydreamforever/article/details/61429140

在C++中,inline关键字和virtual关键字分别用来定义c++中的内联函数和虚函数,他们在各自的场合都有其各自的应用,下面将简单介绍他们各自的功能,然后在说明为什么一个函数不能同时是虚函数和内联函数(inline)。

一、内联函数(inline)
内联函数的目的是为了减少函数调用时间。它是把内联函数的函数体在编译器预处理的时候替换到函数调用处,这样代码运行到这里时候就不需要花时间去调用函数。但内联函数有个缺点是它会增加执行文件大小。所以如果不适当的使用内联函数会造成执行文件特别大。

而使用内联函数有以下几点需要注意
头文件中不仅要包含inline函数的声明,还要包含inline函数的定义。
编译器需要把inline函数体替换到函数调用处,所以编译器必须要知道inline函数的函数体是啥,所以要将inline函数的函数定义和函数声明一起写在头文件中,便与编译器查找替换。
可以在同一个项目的不同源文件内定义函数名相同,实现相同的inline函数;
同一个inline函数可以多处声明和定义,但是必须要完全相同;
定义在class声明内的成员函数默认是inline函数;

二、虚函数(virtual)
虚函数是为了实现多态特性的。虚函数的调用只有在程序运行的时候才能知道到底调用的是哪个函数,其是有有如下几点需要注意:
类的构造函数不能是虚函数;
构造函数是为了构造对象的,所以在调用构造函数时候必然知道是哪个对象调用了构造函数,所以构造函数不能为虚函数。
类的静态成员函数是虚函数;
类的静态成员函数是该类共用的,与该类的对象无关,静态函数里没有this指针,所以不能为虚函数。

虚函数不能定义为内联函数的原因:
inline是在编译器将函数类容替换到函数调用处,是静态编译的。而虚函数是动态调用的,在编译器并不知道需要调用的是父类还是子类的虚函数,所以不能够inline声明展开,所以编译器会忽略

总结
1.使用inline关键字的函数可能会被编译器忽略而不在调用处展开,如虚函数。

2.如果定义的inline函数过大,为了防止生成的obj文件太大,编译器会忽略这里的inline声明。

3.inline是在编译器将函数类容替换到函数调用处,是静态编译的。而虚函数是动态调用的,在编译器并不知道需要调用的是父类还是子类的虚函数,所以不能够inline声明展开,所以编译器会忽略。

4.头文件中不仅要包含inline函数的声明,还要包含inline函数的定义。

编译器需要把inline函数体替换到函数调用处,所以编译器必须要知道inline函数的函数体是啥,所以要将inline函数的函数定义和函数声明一起写在头文件中,便与编译器查找替换。

5.可以在同一个项目的不同源文件内定义函数名相同,实现相同的inline函数。
同一个inline函数可以多处声明和定义,但是必须要完全相同。

6.定义在class声明内的成员函数默认是inline函数。

7.类的构造函数不能是虚函数。构造函数是为了构造对象的,所以在调用构造函数时候必然知道是哪个对象调用了构造函数,所以构造函数不能为虚函数。

8.类的静态成员函数不能是虚函数。类的静态成员函数是该类共用的,与该类的对象无关,静态函数里没有this指针,所以不能为虚函数。

上一篇:js面试题知识点全解(一闭包)


下一篇:iOS 10 申请隐私权限的一些常用选项