一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的。
但设置虚函数须注意:
1:只有类的成员函数才能说明为虚函数;
原因:普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数。
2:静态成员函数不能是虚函数;
因为static
属于class
自己的,也必须有实体; 没有this指针,它无法进行对象的判别。
3:内联函数不能为虚函数;
原因: inline是编译时展开,必须有实体;内联函数就是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。(再说了,inline函数在编译时被展开,虚函数在运行时才能动态的邦定函数)
4:构造函数不能是虚函数;原因:
原因:析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。构造一个CStudent的动态对象如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。类析构函数要声明为虚函数这样派生类调用析构函数才能层层回调,释放资源。这也是虚函数的作用--提供回调的指针。
C++中,哪些函数不可以被声明为虚函数
总的来说,共有五种,普通函数(非成员函数)、构造函数、内联函数、静态函数、友元函数。
首先说明两点:
(1)虚函数是为了实现多态,而多态是属于动态联编,在运行时确定调用哪个函数。
(2)虚函数调用时,类之间需要有公有继承 +继承关系 + 基类指针或引用调用。
具体解释
(1)普通函数为啥不能是虚函数?
原因:多态是依托于类的,要声明的多态的函数前提必须是虚函数。
(2)构造函数为啥不能是虚函数?
原因:多态是依托于类的,多态的使用必须是在类创建以后,而构造函数是用来创建构造函数的,所以不行。
具体的原因:虚表指针的初始化时在构造函数进行的,而虚函数需要放到虚表中。在调用虚函数前,必须首先知道虚表指针,此时矛盾就出来了。
(3)内联函数为啥不能是虚函数?
原因:内联函数属于静态联编,即内联函数是在编译期间直接展开,可以减少函数调用的花销,即是编译阶段就确定调用哪个函数了。但是虚函数是属于动态联编,即是在运行时才确定调用哪一个函数。显然这两个是冲突的。
(4)静态函数为啥不能使虚函数?
原因:
<1>从技术层面上说,静态函数的调用不需要传递this指针。但是虚函数的调用需要this指针,来找到虚函数表。相互矛盾
<2>从存在的意义上说,静态函数的存在时为了让所有类共享。可以在对象产生之前执行一些操作。与虚函数的作用不是一路的。
(5)友元函数为啥不能是虚函数?
原因:C++不支持友元函数的继承,不能继承的函数指定不是虚函数。