zoukankan      html  css  js  c++  java
  • 学习继承和虚析构函数

    练习代码,该说的都在代码和注释里:

      1 #include <string>
      2 
      3 class BaseClass 
      4 {
      5 private:
      6     int pri;
      7 protected:
      8     int pro;
      9 public:
     10     int pub;
     11 
     12     BaseClass()
     13     {
     14         printf("调用父类的构造函数!
    ");
     15         to_string();
     16     }
     17 
     18     // 将析构函数设置为虚函数,以便在应用多态特征的时候,能够调用子类的析构函数释放子类动态申请的空间
     19     virtual ~BaseClass()    
     20     {
     21         printf("调用父类的析构函数!
    ");
     22     }
     23     virtual void to_string()
     24     {
     25         printf("调用父类的to_string:我是父类!
    ");
     26     }
     27     void do_something()
     28     {
     29         printf("我什么也没干!
    ");
     30     }
     31 };
     32 
     33 class DerivedClassPub : public BaseClass
     34 {
     35 private:
     36     char* name;
     37 public:
     38     DerivedClassPub()
     39     {
     40         printf("调用子类的构造函数!
    ");
     41         pub = 1;    // 还是public
     42         pro = 1;    // 还是protected
     43 //        pri = 1; 非法,不可访问
     44         const char* str = "小强";
     45         name = new char[strlen(str)+1];
     46         strcpy(name, str);
     47         to_string();
     48     }
     49     ~DerivedClassPub()
     50     {
     51         printf("调用子类的析构函数!
    ");
     52 
     53         // 如果父类的析构函数不是虚函数,在应用多态特性时:如使用父类的指针或者引用指向子类时,子类的析构函数不会被调用,动态申请的空间无法被释放
     54         delete name;
     55         name = NULL;
     56     }
     57     void to_string()
     58     {
     59         printf("调用子类的to_string:我是子类!我的名字是:%s
    ", name);
     60     }
     61     void do_something()
     62     {
     63         printf("我在跑步!
    ");
     64     }
     65 };
     66 
     67 class DerivedClassPro : protected BaseClass
     68 {
     69 public:
     70     DerivedClassPro()
     71     {
     72         pub = 1;    // 变成protected
     73         pro = 1;    // 还是protected
     74 //        pri = 1; 非法,不可访问
     75     }
     76     ~DerivedClassPro(){}
     77 };
     78 
     79 class DerivedClassPri : private BaseClass
     80 {
     81 public:
     82     DerivedClassPri()
     83     {
     84         pub = 1;    // 变成private
     85         pro = 1;    // 变成private
     86 //        pri = 1; 非法,不可访问
     87     }
     88     ~DerivedClassPri(){}
     89 };
     90 
     91 class AnotherBaseClass
     92 {
     93 public:
     94     AnotherBaseClass()
     95     {
     96         printf("调用父类的构造函数!
    ");
     97     }
     98     ~AnotherBaseClass()
     99     {
    100         printf("调用父类的析构函数!
    ");
    101     }
    102 };
    103 class AnotherDerivedClass : public AnotherBaseClass
    104 {
    105 public:
    106     AnotherDerivedClass()
    107     {
    108         printf("调用子类的构造函数!
    ");
    109     }
    110     ~AnotherDerivedClass()
    111     {
    112         printf("调用子类的析构函数!
    ");
    113     }
    114 };
    115 
    116 int main()
    117 {
    118     // 构造的时候,先调用父类的构造函数,若其中调用了任何虚函数和非虚函数,均是父类的函数,因为此时还没构造出子类的那部分,换句话说,现在才构造了一半
    119     BaseClass* base = new DerivedClassPub();
    120 
    121     // 因为析构函数是虚函数,所以调用子类的析构函数,之后再调用父类的析构函数,为什么?
    122     printf(">> 当析构函数是虚函数时:
    ");
    123     delete base;
    124     printf("<< 结束!
    
    
    ");
    125     base = NULL;
    126 
    127     AnotherBaseClass* another_base = new AnotherDerivedClass();
    128     printf(">> 当析构函数不是虚函数时:
    ");
    129     delete another_base;
    130     printf("<< 结束!
    
    
    ");
    131     another_base = NULL;
    132 
    133     DerivedClassPub* d = new DerivedClassPub();
    134     printf(">> 当析构函数是虚函数时:
    ");
    135     delete d;
    136     printf("<< 结束!
    
    
    ");
    137     d = NULL;
    138 
    139     AnotherDerivedClass* ad = new AnotherDerivedClass();
    140     printf(">> 当析构函数不是虚函数时:
    ");
    141     delete ad;
    142     printf("<< 结束!
    
    
    ");
    143     ad = NULL;
    144 
    145     return 0;
    146 }

    输出结果:

    调用父类的构造函数!
    调用父类的to_string:我是父类!
    调用子类的构造函数!
    调用子类的to_string:我是子类!我的名字是:小强
    >> 当析构函数是虚函数时:
    调用子类的析构函数!
    调用父类的析构函数!
    << 结束!
    
    
    调用父类的构造函数!
    调用子类的构造函数!
    >> 当析构函数不是虚函数时:
    调用父类的析构函数!
    << 结束!
    
    
    调用父类的构造函数!
    调用父类的to_string:我是父类!
    调用子类的构造函数!
    调用子类的to_string:我是子类!我的名字是:小强
    >> 当析构函数是虚函数时:
    调用子类的析构函数!
    调用父类的析构函数!
    << 结束!
    
    
    调用父类的构造函数!
    调用子类的构造函数!
    >> 当析构函数不是虚函数时:
    调用子类的析构函数!
    调用父类的析构函数!
    << 结束!
    
    
    请按任意键继续. . .
  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3343822.html
Copyright © 2011-2022 走看看