c++面试常见问题总结

近来在面试的过程,发现面试官在c++方面总是喜欢问及的一些相关问题总结,当时没怎么答出来,或者是答的不怎么全面,故而查询相关资料总结下。(后面实际工作会进行实时更新信息)

<一>c++虚函数方面

    虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

那么虚函数表的指针存放在哪里呢?

上述已经描述过了,存放在具体的实例对象中,通过虚函数指针来操控虚函数表,在进行多态的时候,需要用到,根据具体的实例对象就能确定所要调用的时哪一个具体类的具体方法。都是通过虚函数表来完成相应的操作的。在虚函数表中存放的时具体实例类重写的父类的虚函数方法地址。当调用时,根据具体的实例即可访问到具体方法。综上所述虚函数可以概括为以下几点:

a>虚函数表是全局共享元素,全局就只有一个。

b>虚函数表好比是一个类似数组的东西,再类对象中存储vptr(虚函数指针),因为其不属于方法,也不属于代码,所以不能存放在代码段。

c>虚函数表中存储的时虚函数的方法的地址,其大小在编译节点就已经确定好了,根据相关的继承关系,就能确定好虚函数表的大小。所以不用动态的分配内存,不在堆中。

d>由于虚函数表是全局共享的,类似于static变量一样,存储在全局代码区域。

<二>有关c++类占用内存的多少计算

 在c++中一个空类所占内存的大小为1字节,例如:

  class A{};  计算其占用内存大小:sizeof(A) = 1;为什么一个空类的大小占用1字节呢?是因为类的实例化实质上就是在内存中分配一块独一无二地址,这样保证了实例是唯一存在的。所以,给空类分配一个字节,就相当于给实例分配了一个地址。如果不隐含包含一个字节的话,就不能进行实例化。当该类作为基类被继承的时候,系统会优化该类成为0字节,这个被称为空白基类最优化过程。

以下几种类型的类占用内存字节的大小,在32位系统下:

class A{};  sizeof(A) = 1;该大小上述已经具体化介绍。

//只包含成员函数的类

class B{

  public:

     B(){}

     ~B(){}

};

sizeof(B) = 1;  

//包含成员变量的类

class C{

  public:

     C(){}

     ~C(){}

 private:

   int c;

};

sizeof(C) = 4 ;

//包含虚函数的类

class D{

  public:

     D(){}

     virtual ~D(){}

 private:

   int d;

};

sizeof(D) =  8;

//包含继承关系的类

class E:public D{

    public:

      E(){}

      ~E(){}

    private:

      int e;

};

sizeof(E) = 8;


从以上A到E几个实例来解释该类所占用内存大小的原因。

A类,是一个空类,因为空类也可以进行实例化,实例化就需要系统分配一块唯一地址的内存,所有系统隐含添加一个字节大小。

B类,虽然包含有构造函数和析构函数,但是在类中,成员函数是不占用内存的,另外该类并无成员变量,所以占用的内存大小和仍旧是1字节。同样是需要实例化所需要的。

C类,包含成员变量,系统给成员变量按照实际类型来分配具体内存大小的。例如,一个int型变量,占用4字节,所有sizeof(C) = 4.

D类,存在虚函数的类都有一个一维的虚函数表叫虚表,虚表里存放的就是虚函数的地址了,因此,虚表是属于类的。这样的类对象的前四个字节是一个指向虚表的指针,类内部必须得保存这个虚表的起始指针。在32位的系统分配给虚表指针的大小为4个字节,得到类D的大小为4,所以在算上成员变量d所占用的字节数,sizeof(D) = 8;

E类,继承了D类,E类和D类共享一个虚函数指针,故而算上E类自身的一个成员变量e,sizeof(E) = 8;

综上所述:

 空类:占用一个字节大小,因为每一个类都需要实例化时分配一块独一无二的内存空间。

 类内部:普通成员变量根据各自类型占用相应的内存大小,但是static变量不含用,其存放在全局区域。子类继承父类,则将父类的成员变量计算进入子类占用的大小。非虚的成员函数不占用内存大小,但是虚函数,需要维护一张虚函数表存放相应的虚函数地址,所以虚函数指针才类内部,指针占用相应的内存大小,并且继承之后,父子类共享此虚指针。

 







猜你喜欢

转载自blog.csdn.net/qq_26105397/article/details/80585613