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:我是子类!我的名字是:小强
    >> 当析构函数是虚函数时:
    调用子类的析构函数!
    调用父类的析构函数!
    << 结束!
    
    
    调用父类的构造函数!
    调用子类的构造函数!
    >> 当析构函数不是虚函数时:
    调用子类的析构函数!
    调用父类的析构函数!
    << 结束!
    
    
    请按任意键继续. . .
  • 相关阅读:
    springBoot Mybaits分页错误
    验证码的技术实现原理
    《参与感》----产品篇
    参与感三三法则
    MIUI 的参与感
    从 UI 交互角度说语音识别产品
    语音识别开放平台调研以及主要技术
    测试蓝牙回连技术
    测试语音遥控器语音聊天的坑
    测试语音遥控器扫描连接的要点
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3343822.html
Copyright © 2011-2022 走看看