分享

c++ 继承 向下造型与向下造型 隐式转换 显示转换

 GLL_ 2018-05-27
 

1 继承的基本概念

  通过一种机制表达类型之间的共性和特性的方式,利用已有的数据类型定义新的数据类型,这种机制称为继承。

eg:

人类:姓名、年龄、吃饭、睡觉

学生类:姓名、年龄、学号、吃饭、睡觉、学习

教师类:姓名、年龄、工资、吃饭、睡觉、授课

 

人类:姓名、年龄、吃饭、睡觉

学生类继承人类:学号、学习

教师类继承人类:工资、授课

 

       人类(基类/父类)

      /      \   

   学生类    教师类(派生类/子类)

 

   基类派生子类,子类继承基类

 

2 继承语法

  class 子类:继承方式1 基类1,继承方式2 基类2...{

     ...

  };

继承方式:public、protected、private

eg:

class Human{

public:

   int age;

   string name;

};

class Student:public Human{

   //Student继承了Human类

   //Student类存在一份Human类中的成员

};

 

3 继承的特性(public)

3.1 向上造型(重点掌握)

   将子类类型的指针或引用转换为基类类型的指针或引用。这种操作性缩小的类型转换,在编译器看来是安全的,因此可以隐式完成。

 

3.2 向下造型:

   将基类类型的指针或引用转换为子类类型的指针或引用。这种操作性扩大的类型转换,在编译器看来是危险的,因此必须显示的完成。


​用一个人,学生,教师类来说吧

​ 1 #include <iostream>
  2 using namespace std;
  3
  4 class Human{
  5     public:
  6         Human(const string &name,int age):
  7             m_name(name),m_age(age),m_id(100){}
  8         void eat(const string &food)const{
  9             cout << "我在吃" << food << endl;
 10         }
 11         void sleep(int time)const{
 12             cout << "我睡了" << time << "小时." << endl;
 13         }
 14     protected: //保护类型成员可以在类的内部和子类中访问
 15         string m_name;
 16         int m_age;
 17         //私有成员子类无法直接访问,但可以共有或保护的
 18         //接口函数来间接访问
 19         const int &get_id(void)const{
 20             return m_id;
 21         }
 22     private:
 23         int m_id;
​ 24 };
 25 //学生类,继承人类
 26 class Student:public Human{
 27     public:
 28     //基类子对象:子类对象包含基类中的那部分成员
 29     //通过初始化表显示指名基类子对象的初始化方式
 30         Student(const  string &name,int age,int no):
 31             Human(name,age),m_no(no){}
 32         void who(void)const{
 33             cout << "我叫" << m_name << "今年" << m_age <<
 34                 "岁,学号是" << m_no << endl;
 35                 
 36         }
 37         void learn(const string &course)const{
 38             cout << "我在学" << course << endl;
 39         }
 40     private:
 41         int m_no;
 42
 43 };
 44 //教师类,继承子类
​ 45 class Teacher:public Human{
 46     public:
 47         Teacher(const string &name,int age,double salary):
 48             Human(name,age),m_salary(salary){}
 49         void who(void){
 50             cout << "我叫" << m_name << "今年" << m_age
 51                 << "岁,每月的薪水为:" << m_salary << endl;
 52         }
 53         void teach(const string &course)const{
 54             cout << "我在教" << course << endl;
 55         }
 56     private:
 57         double m_salary;
 58 };
 59 int main(void){
 60     Student s("悟空",30,10011);
 61     s.who();
 62     s.eat("芒果");
 63     s.sleep(8);
 64     s.learn("念经");
 65     Teacher t("三藏",35,1000);
 66     t.who();
 67     t.sleep(6);

​ 68     t.teach("佛法");
 69
 70     //向上造型,安全,可以隐式转换
 71     //ph:指向子类对象的基类指针
 72     Human *ph = &s;  //缩小操作范围,可以
 73     ph->eat("桃子");
 74     ph->sleep(10);
 75     //ph->who() 这句出错,已经转换为基类型了,无法操作子类
 76
 77     //安全的向下造型,必须显示完成
 78     Student *ps = static_cast<Student *>(ph); //扩大操作范围,安全
 79     ps->who();
 80
 81     //危险的向下造型  //因为不知道那个内存空间大于基类的空间存的什么内容
 82     Human h("张飞",28);
 83     ps = static_cast<Student *>(&h); //扩大操作范围,危险
 84     ps->who();
 85     return 0;
 86 }
 
 


tarena@ubuntu:~/cplus/day08$ g++ 02inheritance.cpp
tarena@ubuntu:~/cplus/day08$ ./a.out
我叫悟空今年30岁,学号是10011
我在吃芒果
我睡了8小时.
我在学念经
我叫三藏今年35岁,每月的薪水为:1000
我睡了6小时.
我在教佛法
我在吃桃子
我睡了10小时.
我叫悟空今年30岁,学号是10011
我叫张飞今年28岁,学号是18407464



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多