虚函数 虚继承 sizeof

来源:互联网 发布:js调用api截屏 qt 编辑:程序博客网 时间:2024/05/03 16:30
#include <iostream>  using namespace std;    class A  {  public:      A(){}      A(int a):m_a(a){}      virtual void print()      {          cout<<"A::"<<m_a<<endl;      }  private:      int m_a;  };    class B:public virtual A  {  public:      B(){}      B(int a, int b):A(a),m_b(b){}      virtual void print()      {          A::print();          cout << "B::" << m_b << endl;      }  private:      int m_b;  };    int main()  {      cout<< "sizeof(A):" << sizeof(A)<<endl; //sizeof(A) = sizeof(指向A中虚函数print的指针) + sizeof(m_a)     cout<< "sizeof(B):" << sizeof(B)<<endl;//sizeof(B)=sizeof(A)+sizeof(m_b)+sizeof(指向B中虚函数print的指针)+sizeof(指向父类A的指针(虚继承)) return 0;}

输出结果为:


/*******************************************************************************************************/class demo  {  public:      virtual void f(int){}      virtual void f(double){}      virtual void g(int){}  };    class Derived:public demo  {          virtual void g(int){}  };  cout << sizeof(Derived) << endl; // 输出结果为4,多个虚函数放到一个表里,所以虚函数指针只要一个就行了。/*******************************************************************************************************/class demo  {  public:      virtual void f(int){}      virtual void f(double){}      virtual void g(int){}  };    class Derived:public demo  {          virtual void gt(int){}  };    cout << sizeof(Derived) << endl;// 输出结果为4,多个虚函数放到一个表里,所以虚函数指针只要一个就行了。/*******************************************************************************************************/class demo  {  public:      virtual void f(int){}      virtual void f(double){}      virtual void g(int){}  };    class Derived:public virtual demo  {          virtual void g(int){}  };   cout<<sizeof(Derived)<<endl;  //输出结果为8 ,此为虚继承,子类复制父类的所有内容,并定义一个指针指向复制过来的内容。函数g覆盖掉虚表中的函数。 /*******************************************************************************************************/class demo  {  public:      virtual void f(int){}      virtual void f(double){}      virtual void g(int){}  };    class Derived:public virtual demo  {          virtual void gt(int){}  };  cout<<sizeof(Derived)<<endl;  //输出结果为12 ,子类还要定义一个虚指针,指向自己的虚表,把函数gt插入虚表,如果为多继承,则定义多个虚表。

1.常规 char str1[] = “Hello” ;  char str2[5] = {'H','e','l','l','o'};  char str3[6] = {'H','e','l','l','o','/0'};  char   *p1 = "Hello";  char *p2[]={"hello","world"};   int     n = 10;  int    *q = &n;    sizeof (str1 ) = 6      //自动加了'/0'    strlen (str1 ) = 5      //字符串的长度    sizeof (str2 ) = 5      //字符数组的大小  strlen (str2) = 未知    //该字符串缺少结束符'/0'  sizeof (str3) = 6       //字符数组的大小  strlen (str3) = 5       //该字符串的长度为5  sizeof ( p1 ) =   4     //p1是一个指针,大小为4  sizeof ( p2 ) =   8     //p2是长度为2的字符串数组  sizeof ( n ) =   4      //整型大小为4  sizeof ( q ) =   4      //q是一个指针,大小为4  2.动态分配内存int *p = (int *)malloc( 100 );  sizeof ( p ) = 4      //p是一个指针,大小为4   3.函数参数 void Function1( char p[],int num ){      sizeof ( p ) = 4 //(数组在做为函数参数时均化为指针)  }  void Function2( int p[],int num ){      sizeof ( p ) = 4 //(数组在做为函数参数时均化为指针)  }    4.多重继承class A{};  class B{};  class C:public A,public B{};  class D:virtual public A{};  class E:virtual public A,virtual public B{};  sizeof ( A ) = 1      //空类大小为1,编译器安插一个char给空类,用来标记它的每一个对象  sizeof ( B ) = 1      //空类大小为1,编译器安插一个char给空类,用来标记它的每一个对象  sizeof ( C ) = 1      //继承或多重继承后空类大小还是1  sizeof ( D ) = 4      //虚继承时编译器为该类安插一个指向父类的指针,指针大小为4 sizeof ( E ) = 8      //指向父类A的指针与父类B的指针,加起来大小为8    5.数据对齐  //类(或结构)的大小必需为类中最大数据类型的整数倍.CPU访问对齐的数据的效率是最高的,因此通常编译浪费一些空间来使得我们的数据是对齐的  class A{  public:      int a;  };  class B{  public:       int a ;      char b;  };  class C{  public:       int a ;      char b;      char c;  };  sizeof(A) = 4   //内含一个int ,所以大小为4  sizeof(B) = 8   //int为4,char为1,和为5,考虑到对齐,总大小为int的整数倍即8    sizeof(C) = 8   //同上    6.函数与虚函数 //编译器为每个有虚函数的类都建立一个虚函数表(其大小不计算在类中,并为这个类安插一个指向虚函数表的指针,即每个有虚函数的类其大小至少为一个指针的大小4  class A{  public:      int a;      void Function();  };  class B{  public:      int a;      virtual void Function();  };  class C:public B{  public:      char b;  };  class D:public B{  public:      virtual void Function2();  };  class E{  public:      static void Function();  };  sizeof (A) = 4   //内含一个int,普通函数不占大小  sizeof (B) = 8   //一个int ,一个虚函数表指针  sizeof (C) =12   //一个int ,一个虚函数表指针,一个char ,再加上数据对齐  sizeof (D) = 8   //一个int ,一个虚函数表指针,多个虚函数是放在一个表里的,所以虚函数表指针只要一个就行了  sizeof (E) = 1   //static 函数不占大小,空类大小为1    7.父类的私有数据//虽然在子类中不可用,但是是可见的,因此私有的数据还是要占子类的大小  class A{  private:      int a;  };  class B:public A{};  sizof(B) = 4;    //内含一个不可用的父类的int  8.大概就这么多了吧,想到再加吧。虚函数,多重继承,空类是比较复杂的,大家大概记住知道就行了            weiloujushi补充:    class static_D  {  int static intVar;     static void fun(){}    };    sizeof(static_D) ==1 //静态数据成员不计入类内  

//我们用sizeof测一个类所占内存空间的大小时,会得到什么结果,虚函数表有什么影响?    //如果一个类里面什么也不实现,只实现一个或多个虚函数的话,测它的sizeof会得到4,但如果一个类从多个类继承,并且它的多个基类有虚函数的话,它就会有多个虚函数表了,这个在COM也有体现.如下例  class A  {  public:  virtual void PrintA1(void)  {  }  virtual void PrintA2(void)  {  }  };  class B  {  public:  virtual void PrintB(void)  {  }  };  class C  {  public:  virtual void PrintC(void)  {  }  };  class D : public A, public B, public C  {  };  测试结果是  sizeof(D) = 12;  如果D类改成下面的样子,即在它里面再加一个虚函数,结果还是12  class D : public A, public B, public C  {  public:  virtual void PrintD(void)  {  }  };  但要注意的是有虚基类后情况就又不同了,具体的还要调查. 

引用地址:http://blog.csdn.net/wangyangkobe/article/details/5951248

0 0
原创粉丝点击