我们来看一下牛客网上的这个题
牛客网" />
还是先分析一下每个选项之后再重点讲一下A选项
- A:内联函数在编译期间将调用之处用被调函数来代替,而虚函数在运行时才能确定调用哪个函数,所以虚函数声明为内联不能提高效率,不是虚函数不能被声明为内联,这个我们稍后详细的说。
- B:类里面存着相同函数名和参数的函数时,在调用时都会出现冲突,不知调用哪一个。
- C:delete子类对象是一定会调用父类的析构函数的,先调用子类的析构函数然后调用父类的析构函数;如果要调用父类指向子类的对象的指针,此时才需要父类的析构函数是虚的。
内联函数(inline)
- 内联函数的目的是为了减少函数调用时间。它是把内联函数的函数体在编译器预处理的时候替换到函数调用处,这样代码运行到这里时候就不需要花时间去调用函数。但内联函数有个缺点是它会增加执行文件大小。所以如果不适当的使用内联函数会造成执行文件特别大。
- 系统可以忽略用户定义的内联函数,若是用户将一个很复杂的函数定义为内联时,此时程序效率不仅不能提高反而更慢时,系统就可以忽略关键字inline,按照正常函数调用。
而使用内联函数有以下几点需要注意:
- 头文件中不仅要包含inline函数的声明,还要包含inline函数的定义。
- 编译器需要把inline函数体替换到函数调用处,所以编译器必须要知道inline函数的函数体是啥,所以要将inline函数的函数定义和函数声明一起写在头文件中,便与编译器查找替换。
- 可以在同一个项目的不同源文件内定义函数名相同,实现相同的inline函数。
- 同一个inline函数可以多处声明和定义,但是必须要完全相同。
- 定义在class声明内的成员函数默认是inline函数。
虚函数(virtual)
其是有有如下几点需要注意:
- 类的构造函数不能是虚函数,构造函数是为了构造对象的,所以在调用构造函数时候必然知道是哪个对象调用了构造函数,所以构造函数不能为虚函数。
- 类的静态成员函数是虚函数,类的静态成员函数是该类共用的,与该类的对象无关,静态函数里没有this指针,所以不能为虚函数。
- 类的析构函数最好定义为虚函数,因为在析构一个指向子类对象的父类指针时,若是析构函数不为虚函数,此时释放该指针时只调用父类析构函数,这样子类的资源不会被释放就会造成内存泄漏的情况。详细解释可参见博客 https://blog.csdn.net/chenxiyuehh/article/details/88775057
《Effective C++》的第33款:
即使是最简单的虚函数调用,编译器的内联处理程序对它也爱莫能助。(这一点也不奇怪。virtual的意思是"等到运行时再决定调用哪个函数",inline的意思是"在编译期间将调用之处用被调函数来代替",如果编译器甚至还不知道哪个函数将被调用,当然就不能责怪它拒绝生成内联调用了)。
虚函数与内联函数
- 虚函数用于实现运行时的多态,或者称为晚绑定或动态绑定。而内联函数用于提高效率。内联函数的原理是,在编译期间,对调用内联函数的地方的代码替换成函数代码。内联函数对于程序中需要频繁使用和调用的小函数非常有用。
- 默认地,类中定义的所有函数,除了虚函数之外,会隐式地或自动地当成内联函数(注意:内联只是对于编译器的一个请求,编译器可以自己决定是否进行内联).
- 无论何时,使用基类指针或引用来调用虚函数,它都不能为内联函数(因为调用发生在运行时,运行时才会确定具体调用哪一个函数)。但是,无论何时,使用类的对象(不是指针或引用)来调用时,可以当做是内联,因为编译器在编译时确切知道对象是哪个类的。
举个栗子看看
#include <iostream>
using namespace std;
class Base
{
public:
virtual void who()
{
cout << "I am Base\n";
}
};
class Derived : public Base
{
public:
void who()
{
cout << "I am Derived\n";
}
};
int main()
{
// 此处的虚函数who(),是通过类的具体对象来调用的,编译期间就能确定了,所以它可以是内联的。
Base b;
b.who();
// 此处的虚函数是通过指针调用的,需要在运行时期间才能确定,所以不能为内联。
Base *ptr = new Derived();
ptr->who();
return 0;
}
虚函数" />
通过这两幅图我们我们可以知道虚函数用指针或是引用调用时是在程序运行时确定是调用哪一个函数的,因此这种情况下是无法将虚函数声明为内联函数的
若是想要了解更多关于内联函数什么情况下可以被声明为内联函数,可以参加博客,有详细的解释 https://blog.csdn.net/zy1691/article/details/3606128