虚函数、虚继承、sizeof

来源:互联网 发布:d3.js demo显示 编辑:程序博客网 时间:2024/04/20 18:56
  1. // 练习.cpp : 定义控制台应用程序的入口点。  
  2.   
  3. #include "stdafx.h"  
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. class A  
  8. {  
  9. public:  
  10.     A(){}  
  11.     A(int a):m_a(a){}  
  12.     virtual void print()  
  13.     {  
  14.         cout<<"A::"<<m_a<<endl;  
  15.     }  
  16. private:  
  17.     int m_a;  
  18. };  
  19.   
  20. class B:public virtual A  
  21. {  
  22. public:  
  23.     B(){}  
  24.     B(int a, int b):A(a),m_b(b){}  
  25.     virtual void print()  
  26.     {  
  27.         A::print();  
  28.         printf("B::%d/n", m_b);  
  29.     }  
  30. private:  
  31.     int m_b;  
  32. };  
  33.   
  34. int main()  
  35. {  
  36.     cout<<sizeof(A)<<endl;  
  37.     cout<<sizeof(B)<<endl;//sizeof(B)=sizeof(A)+sizeof(m_b)+sizeof(指向B中虚函数print的指针)+sizeof(指向父类A的指针(虚继承))  
  38. }  

[cpp] view plaincopy
  1. class demo  
  2. {  
  3. public:  
  4.     virtual void f(int){}  
  5.     virtual void f(double){}  
  6.     virtual void g(int){}  
  7. };  
  8.   
  9. class Derived:public demo  
  10. {  
  11.         virtual void g(int){}  
  12. };  
  13.   
  14. cout<<sizeof(Derived)<<endl;  
  15. 输出结果为4  
  16.   
  17. class demo  
  18. {  
  19. public:  
  20.     virtual void f(int){}  
  21.     virtual void f(double){}  
  22.     virtual void g(int){}  
  23. };  
  24.   
  25. class Derived:public demo  
  26. {  
  27.         virtual void gt(int){}  
  28. };  
  29.   
  30. cout<<sizeof(Derived)<<endl;  
  31. 输出结果为4  
  32.   
  33. class demo  
  34. {  
  35. public:  
  36.     virtual void f(int){}  
  37.     virtual void f(double){}  
  38.     virtual void g(int){}  
  39. };  
  40.   
  41. class Derived:public virtual demo  
  42. {  
  43.         virtual void g(int){}  
  44. };  
  45.   
  46. cout<<sizeof(Derived)<<endl;  
  47. 输出结果为8  
  48.   
  49. 此为虚继承,子类复制父类的所有内容,并定义一个指针指向复制过来的内容。函数g覆盖掉虚表中的函数。  
  50.   
  51. class demo  
  52. {  
  53. public:  
  54.     virtual void f(int){}  
  55.     virtual void f(double){}  
  56.     virtual void g(int){}  
  57. };  
  58.   
  59. class Derived:public virtual demo  
  60. {  
  61.         virtual void gt(int){}  
  62. };  
  63.   
  64. cout<<sizeof(Derived)<<endl;  
  65. 输出结果为12  
  66.   
  67. 子类还要定义一个虚指针,指向自己的虚表,把函数gt插入虚表。  
  68.   
  69. 如果为多继承,则定义多个虚表。  
 
[cpp] view plaincopy
  1. 1.常规  
  2. char str1[] = “Hello” ;  
  3. char str2[5] = {'H','e','l','l','o'};  
  4. char str3[6] = {'H','e','l','l','o','/0'};  
  5. char   *p1 = "Hello";  
  6. char *p2[]={"hello","world"};   
  7. int     n = 10;  
  8. int    *q = &n;  
  9.   
  10. sizeof (str1 ) = 6    (自动加了'/0')    
  11. strlen (str1 ) = 5    (字符串的长度)    
  12. sizeof (str2 ) = 5     (字符数组的大小)  
  13. strlen (str2) = 未知 (该字符串缺少结束符'/0')  
  14. sizeof (str3) = 6     (字符数组的大小)  
  15. strlen (str3) = 5    (该字符串的长度为5)  
  16. sizeof ( p1 ) =   4    (p1是一个指针,大小为4)  
  17. sizeof ( p2 ) =   8    (p2是长度为2的字符串数组)  
  18. sizeof ( n ) =   4    (整型大小为4)  
  19. sizeof ( q ) =   4    (q是一个指针,大小为4)  
  20.   
  21. 2.动态分配内存  
  22. int *p = (int *)malloc( 100 );  
  23. sizeof ( p ) = 4      (p是一个指针,大小为4)  
  24.   
  25. 3.函数参数  
  26. void Function1( char p[],int num ){  
  27.     sizeof ( p ) = 4 (数组在做为函数参数时均化为指针)  
  28. }  
  29. void Function2( int p[],int num ){  
  30.     sizeof ( p ) = 4 (数组在做为函数参数时均化为指针)  
  31. }  
  32.   
  33. 4.多重继承  
  34. class A{};  
  35. class B{};  
  36. class C:public A,public B{};  
  37. class D:virtual public A{};  
  38. class E:virtual public A,virtual public B{};  
  39. sizeof ( A ) = 1      (空类大小为1,编译器安插一个char给空类,用来标记它的每一个对象)  
  40. sizeof ( B ) = 1      (空类大小为1,编译器安插一个char给空类,用来标记它的每一个对象)  
  41. sizeof ( C ) = 1      (继承或多重继承后空类大小还是1)  
  42. sizeof ( D ) = 4      (虚继承时编译器为该类安插一个指向父类的指针,指针大小为4)  
  43. sizeof ( E ) = 8      (指向父类A的指针与父类B的指针,加起来大小为8)  
  44.   
  45. 5.数据对齐  
  46. 类(或结构)的大小必需为类中最大数据类型的整数倍.CPU访问对齐的数据的效率是最高的,因此通常编译浪费一些空间来使得我们的数据是对齐的  
  47. class A{  
  48. public:  
  49.     int a;  
  50. };  
  51. class B{  
  52. public:  
  53.      int a ;  
  54.     char b;  
  55. };  
  56. class C{  
  57. public:  
  58.      int a ;  
  59.     char b;  
  60.     char c;  
  61. };  
  62. sizeof(A) = 4 (内含一个int ,所以大小为4)  
  63. sizeof(B) = 8    (int为4,char为1,和为5,考虑到对齐,总大小为int的整数倍即8)    
  64. sizeof(C) = 8   (同上)  
  65.   
  66. 6.函数与虚函数  
  67. 编译器为每个有虚函数的类都建立一个虚函数表(其大小不计算在类中),并为这个类安插一个指向虚函数表的指针,即每个有虚函数的类其大小至少为一个指针的大小4  
  68. class A{  
  69. public:  
  70.     int a;  
  71.     void Function();  
  72. };  
  73. class B{  
  74. public:  
  75.     int a;  
  76.     virtual void Function();  
  77. };  
  78. class C:public B{  
  79. public:  
  80.     char b;  
  81. };  
  82. class D:public B{  
  83. public:  
  84.     virtual void Function2();  
  85. };  
  86. class E{  
  87. public:  
  88.     static void Function();  
  89. };  
  90. sizeof (A) = 4   (内含一个int,普通函数不占大小)  
  91. sizeof (B) = 8   (一个int ,一个虚函数表指针)  
  92. sizeof (C) =12   (一个int ,一个虚函数表指针,一个char ,再加上数据对齐)  
  93. sizeof (D) = 8   (一个int ,一个虚函数表指针,多个虚函数是放在一个表里的,所以虚函数表指针只要一个就行了)  
  94. sizeof (E) = 1   (static 函数不占大小,空类大小为1)  
  95.   
  96. 7.父类的私有数据  
  97. 虽然在子类中不可用,但是是可见的,因此私有的数据还是要占子类的大小  
  98. class A{  
  99. private:  
  100.     int a;  
  101. };  
  102. class B:public A{};  
  103. sizof(B) = 4;    (内含一个不可用的父类的int)  
  104. 8.大概就这么多了吧,想到再加吧。虚函数,多重继承,空类是比较复杂的,大家大概记住知道就行了  
  105.   
  106.    
  107.   
  108.    
  109.   
  110. weiloujushi补充:  
  111.   
  112. class static_D  
  113. {  
  114. int static intVar;  
  115.    static void fun(){}  
  116.   
  117. };  
  118.   
  119. sizeof(static_D) ==1 //静态数据成员不计入类内  
 
[cpp] view plaincopy
  1. 我们用sizeof测一个类所占内存空间的大小时,会得到什么结果,虚函数表有什么影响?  
  2.   
  3. 如果一个类里面什么也不实现,只实现一个或多个虚函数的话,测它的sizeof会得到4,但如果一个类从多个类继承,并且它的多个基类有虚函数的话,它就会有多个虚函数表了,这个在COM也有体现.如下例  
  4. class A  
  5. {  
  6. public:  
  7. virtual void PrintA1(void)  
  8. {  
  9. }  
  10. virtual void PrintA2(void)  
  11. {  
  12. }  
  13. };  
  14. class B  
  15. {  
  16. public:  
  17. virtual void PrintB(void)  
  18. {  
  19. }  
  20. };  
  21. class C  
  22. {  
  23. public:  
  24. virtual void PrintC(void)  
  25. {  
  26. }  
  27. };  
  28. class D : public A, public B, public C  
  29. {  
  30. };  
  31. 测试结果是  
  32. sizeof(D) = 12;  
  33. 如果D类改成下面的样子,即在它里面再加一个虚函数,结果还是12  
  34. class D : public A, public B, public C  
  35. {  
  36. public:  
  37. virtual void PrintD(void)  
  38. {  
  39. }  
  40. };  
  41. 但要注意的是有虚基类后情况就又不同了,具体的还要调查.  

转自:http://blog.csdn.net/wangyangkobe/article/details/5951248

0 0