c::关于虚函数的一点补充

来源:互联网 发布:xps分析软件下载 编辑:程序博客网 时间:2024/05/21 09:36

【普通函数和虚函数调用的区别?】

答:这个区别很重要:
在抽象的继承模型中叫做多态
就是说,你定义一个类,他们具有相同的接口
但是具体的不同的类又有不同的特征,实现之类可能也完全不同
但是你可以用共同的基类指针来管理
虚函数在实现的时候,其实是在类里建了一个隐含的成员变量,是一个指向函数的指针
所以从基类调用也可以调用到继承类定义的成员函数。

【能否在构造函数里调用虚函数?】

先来看一段程序:

#include<iostream>using namespace std;class Base  {  public:      Base()      {          Fuction();      }        virtual void Fuction()      {          cout << "Base::Fuction" << endl;      }  };    class A : public Base  {  public:      A()      {          Fuction();      }        virtual void Fuction()      {          cout << "A::Fuction" << endl;      }  };    // 这样定义一个A的对象,会输出什么?  int main(){A a;return 0;}
可能很多人说输出结果是:

A::FunctionA::Function
如果是这样,首先我们回顾下C++对象模型里面的构造顺序,在构造一个子类对象的时候,首先会构造它的基类,如果有多层继承关系,实际上会从最顶层的基类逐层往下构造(虚继承、多重继承这里不讨论),如果是按照上面的情形进行输出的话,那就是说在构造Base的时候,也就是在Base的构造函数中调用Fuction的时候,调用了子类A的Fuction,而实际上A还没有开始构造,这样函数的行为就是完全不可预测的,因此显然不是这样,实际的输出结果是:
Base::FunctionA::Function

再次小结下:

1)当在构造基类部分时,派生类还没被完全创建,从某种意义上讲此时它只是个基类对象。即当Base::Base()执行时Derive对象还没被完全创建,此时它被当成一个Base对象,而不是Derive对象,因此Foo绑定的是Base的Foo。

2)基类部分在派生类部分之前被构造,当基类构造函数执行时派生类中的数据成员还没被初始化。如果基类构造函数中的虚函数调用被解析成调用派生类的虚函数,而派生类的虚函数中又访问到未初始化的派生类数据,将导致程序出现一些未定义行为和bug

所以不要在构造函数里调用虚函数

【当类中定义了虚函数,但是没有定义构造函数,编译器会为虚函数合成构造函数吗?如果合成,会做什么事?】

   会的,因为编译器会为带有虚函数的成员合成一个虚表

【带有虚函数的类和普通的类有什么区别:】

   多了四个字节(虚表指针)



0 0
原创粉丝点击