zoukankan      html  css  js  c++  java
  • 新标准C++程序设计读书笔记_继承和多态

    简单继承的例子:

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 
     5 class CStudent 
     6 {
     7 private:
     8     string name;
     9     string id; //学号
    10     char gender; //性别,'F'代表女, 'M'代表男
    11     int age;
    12 public:
    13     void PrintInfo();
    14     void SetInfo( const string & name_,const string & id_,
    15     int age_, char gender_ );
    16     string GetName() { return name; }
    17 };
    18 
    19 void CStudent::PrintInfo()
    20 {
    21     cout << "Name:" << name << endl;
    22     cout << "ID:" << id << endl;
    23     cout << "Age:" << age << endl;
    24     cout << "Gender:" << gender << endl;
    25 }
    26 
    27 void CStudent::SetInfo( const string & name_,const string & id_,
    28 int age_,char gender_ )
    29 {
    30     name = name_;
    31     id = id_;
    32     age = age_;
    33     gender = gender_;
    34 }
    35 
    36 class CUndergraduateStudent : public CStudent
    37 {
    38 //本科生类,继承了CStudent类
    39 private:
    40     string department; //学生所属的系的名称
    41 public:
    42     void QualifiedForBaoyan() 
    43     { 
    44         //给予保研资格
    45         cout << “qualified for baoyan” << endl;
    46     }
    47 
    48     void PrintInfo() 
    49     {
    50         CStudent::PrintInfo(); //调用基类的PrintInfo
    51         cout << “Department:” << department <<endl;
    52     }
    53 
    54     void SetInfo( const string & name_,const string & id_,
    55     int age_,char gender_ ,const string & department_) 
    56     {
    57         CStudent::SetInfo(name_,id_,age_,gender_); //调用基类的SetInfo
    58         department = department_;
    59     }
    60 };
    61 
    62 int main()
    63 {
    64     CUndergraduateStudent s2;
    65     s2.SetInfo(“Harry Potter ”, “118829212”,19,‘M’,“Computer Science”);
    66     cout << s2.GetName() << “ ” ;
    67     s2.QualifiedForBaoyan ();
    68     s2.PrintInfo ();
    69     return 0;
    70 }

    类之间的两种关系
    (1)继承:“是”关系。
    基类 A, B是基类A的派生类。逻辑上要求:“一个B对象也是一个A对象”。
    (2)复合:“有”关系。
    类C中“有” 成员变量k, k是类D的对象,则C和D是复合关系,一般逻辑上要求:“ D对象是C对象的固有属性或组成部分”。

    几何形体程序中,需要写“点”类,也需要写“圆”类

    1 class CPoint
    2 {
    3     double x,y;
    4 };
    5 
    6 class CCircle : public CPoint
    7 {
    8     double r;
    9 };

    这是不合理的,应该使用复合关系;每一个“圆”对象里都包含()一个“点”对象,这个“点”对象就是圆心

     1 class CPoint
     2 {
     3     double x,y;
     4     //便于Ccirle类操作其圆心
     5     friend class CCircle;
     6 };
     7 
     8 class CCircle
     9 {
    10     double r;
    11     CPoint center;
    12 };

    覆盖
    派生类可以定义一个和基类成员同名的成员,这叫覆盖。在派生类中访问这类成员时,缺省的情况是访问派生类中定义的成员。要在派生类中访问由基类定义的同名成员时,要使用作用域符号“::”

    访问控制符

    以下均表示可以被下列函数访问

    1、基类的private成员:
    (1)基类的成员函数
    (2)基类的友员函数

    2、基类的public成员:
    (1)基类的成员函数
    (2)基类的友员函数
    (3)派生类的成员函数
    (4)派生类的友员函数
    (5)其他的函数

    3、基类的protected成员:
    (1)基类的成员函数
    (2)基类的友员函数
    (3)派生类的成员函数可以访问当前对象的基类的保护成员

     1 class Father 
     2 {
     3 private: 
     4     int nPrivate; //私有成员
     5 public: 
     6     int nPublic; //公有成员
     7 protected: 
     8     int nProtected; // 保护成员
     9 };
    10 
    11 class Son : public Father
    12 {
    13     void AccessFather () 
    14     {
    15         nPublic = 1; // ok;
    16         nPrivate = 1; // wrong
    17         nProtected = 1; // OK,访问从基类继承的protected成员
    18         Son f;
    19         f.nProtected = 1; //wrong ,f不是当前对象
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     Father f;
    26     Son s;
    27     f.nPublic = 1; // Ok
    28     s.nPublic = 1; // Ok
    29     f.nProtected = 1; // error
    30     f.nPrivate = 1; // error
    31     s.nProtected = 1; //error
    32     s.nPrivate = 1; // error
    33     return 0;
    34 }

    派生类的构造函数

    在创建派生类的对象时,需要调用基类的构造函数:初始化派生类对象中从基类继承的成员。在执行一个派生类的构造函数之前,总是先执行基类的构造函数。

    调用基类构造函数的两种方式
    (1)显式方式:在派生类的构造函数中,为基类的构造函数提供参数.derived::derived(arg_derived-list):base(arg_base-list)
    (2)隐式方式:在派生类的构造函数中,省略基类构造函数时,派生类的构造函数则自动调用基类的默认构造函数.

    派生类的析构函数被执行时,执行完派生类的析构函数后,自动调用基类的析构函数。

    在创建派生类的对象时:
    (1)先执行基类的构造函数,用以初始化派生类对象中从基类继承的成员;
    (2)再执行成员对象类的构造函数,用以初始化派生类对象中成员对象。
    (3)最后执行派生类自己的构造函数

    在派生类对象消亡时:
    (1)先执行派生类自己的析构函数
    (2)再依次执行各成员对象类的析构函数
    (3)最后执行基类的析构函数
    析构函数的调用顺序与构造函数的调用顺序相反。

    赋值规则

    (1)派生类的对象可以赋值给基类对象
    b = d;
    (2)派生类对象可以初始化基类引用
    base & br = d;
    (3)派生类对象的地址可以赋值给基类指针
    base * pb = & d;
    如果派生方式是 privateprotected,则上述三条不可行。

    公有派生的情况下,派生类对象的指针可以直接赋值给基类指针
    Base * ptrBase = &objDerived;
    (1)ptrBase指向的是一个Derived类的对象;
    *ptrBase可以看作一个Base类的对象,访问它的public成员直接通过ptrBase即可,但不能通过ptrBase访问objDerived对象中属于Derived类而不属于Base类的成员
    (2)即便基类指针指向的是一个派生类的对象,也不能通过基类指针访问基类没有,而派生类中有的成员。
    (3)通过强制指针类型转换,可以把ptrBase转换成Derived类的指针
    Base * ptrBase = &objDerived;
    Derived *ptrDerived = (Derived * ) ptrBase;
    要保证ptrBase指向的是一个Derived类的对象,否则很容易会出错。

  • 相关阅读:
    使用JS对中文字符串进行utf8的Base64编码
    subprocess理解
    25组新鲜出炉的有用图标集
    jQuery UI 1.8.9 发布
    正则匹配拼音
    jQuery Mobile 教程 (1)
    10款精选的用于构建良好易用性网站的jQuery插件
    Html 5 video/audio 格式转换 ogg
    10个有用的jquery 图片插件
    asp.net MVC 权限设计(续)
  • 原文地址:https://www.cnblogs.com/abc-begin/p/7780280.html
Copyright © 2011-2022 走看看