虛函數、虛繼承、sizeof

虛函數、虛繼承、sizeof


  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. }  

  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. 如果爲多繼承,則定義多個虛表。  
 
  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 //靜態數據成員不計入類內  
 
  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. 但要注意的是有虛基類後情況就又不同了,具體的還要調查. 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章