zoukankan      html  css  js  c++  java
  • C++继承与派生

    1、继承&派生

    在定义一个新的类B时,若该类与某个已有的类A相似(B拥有A的全部特点),则可以将A作为一个基类,把B作为基类的一个派生类(子类)

    在派生类的各个成员函数中,不能访问基类中的private成员。

    class 派生类名:public 基类名
    {
    };

    派生类对象的体积,等于基类对象的体积+派生类对象自己的成员变量的体积。

    在派生类对象中,包含着基类对象,且基类对象的存储位置位于派生类对象新增的成员变量之前。

    2、继承&复合

    继承:“是”关系。

    – 基类 A,B是基类A的派生类。

    – 逻辑上要求:“一个B对象也是一个A对象”。

    • 复合:“有”关系。

    – 类C中“有”成员变量k,k是类D的对象,则C和D是复合关系

    – 一般逻辑上要求:“D对象是C对象的固有属性或组成部分”。 

    class CMaster; //CMaster必须提前声明,不能先写CMaster类后写Cdog类
    class CDog {
     CMaster * pm;
    };
    class CMaster {
     CDog * dogs[10];
    }; 

     3、访问范围说明符

    (1)private:

    可以被:基类的成员函数、基类的友元函数访问。

    (2)public:

    可以被:基类的成员函数、基类的友元函数、派生类的成员函数、派生类的友元函数、其它函数访问。

    (3)protected

    可以被:基类的成员函数、基类的友元函数访问,且派生类的成员函数可以访问当前对象的基类的保护成员。

    class Father {
    private: int nPrivate; //私有成员
    public: int nPublic; //公有成员
    protected: int nProtected; // 保护成员
    };
    class Son : public Father {
        void AccessFather () {
            nPublic = 1; // ok;
            nPrivate = 1; // wrong
            nProtected = 1; // OK, 访问从基类继承的protected成员
            Son f;
            f.nProtected = 1; //wrong, f不是当前对象
        }
    };
    int main(){
        Father f;
        Son s;
        f.nPublic = 1; // Ok
        s.nPublic = 1; // Ok
        f.nProtected = 1; // error
        f.nPrivate = 1; // error
        s.nProtected = 1; //error
        s.nPrivate = 1; // error
        return 0; 
    }    

    4、派生类的构造函数

    (1)在执行派生类构造函数之前先执行基类构造函数。

    构造函数名(形参表): 基类名(基类构造函数实参表)
    {
    }

    显式方式: 派生类的构造函数中为基类的构造函数提供参数

    derived::derived(arg_derived-list):base(arg_base-list)

    隐式方式:派生类的构造函数中, 省略基类构造函数时,派生类的构造函数, 自动调用基类的默认构造函数

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

    (2)包含成员对象的派生类的构造函数

    class Skill {
     public:
     Skill(int n) { }
    };
    class FlyBug: public Bug {
     int nWings;
     Skill sk1, sk2;
     public:
     FlyBug(int legs, int color, int wings);
    };
    FlyBug::FlyBug( int legs, int color, int wings):
    Bug(legs, color), sk1(5), sk2(color) {
     nWings = wings;
    }

    创建派生类的对象时, 执行派生类的构造函数之前:

    • 调用基类的构造函数,初始化派生类对象中从基类继承的成员

    • 调用成员对象类的构造函数,初始化派生类对象中成员对象

    • 执行完派生类的析构函数后:先调用成员对象类的析构函数,再调用基类的析构函数。析构函数的调用顺序与构造函数的调用顺序相反。

    5、public继承的赋值兼容规则

    class base { };
    class derived : public base { };
    base b;
    derived d;

    (1)派生类的对象可以赋值给基类对象

      b = d;

    (2)派生类对象可以初始化基类的引用

      base &br = d;

    (3)派生类对象的地址可以复制给基类指针

      base *pb = &d;

    Note:若protected或private继承,则不成立。

    6、直接基类与间接基类

    声明派生类时,只需要列出其直接基类。

    派生类的成员包括:派生类自己定义的成员,直接基类中的所有成员、所有间接基类里的全部成员。

    #include <iostream>
    using namespace std;
    class Base {
    public:
        int n;
        Base(int i):n(i) {
            cout << "Base " << n << " constructed" << endl;
        }
        ~Base() {
            cout << "Base " << n << " destructed" << endl;
        }
    };
    class Derived:public Base
    {
    public:
        Derived(int i):Base(i) {
            cout << "Derived constructed" << endl;
        }
        ~Derived() {
            cout << "Derived destructed" << endl;
        }
    };
    class MoreDerived:public Derived {
    public:
        MoreDerived():Derived(4) {
           cout << "More Derived constructed" << endl;
        }
        ~MoreDerived() {
            cout << "More Derived destructed" << endl;
        }
    };
    int main()
    {
        MoreDerived Obj;
        return 0;
    } 
    未经允许,请勿转载
  • 相关阅读:
    POJ 3007 Organize Your Train part II (字典树 静态)
    POJ 3096 Surprising Strings
    移动APP安全测试
    monkey亲测
    PHP笔记
    my sql 只展示 前10条数据的写法
    面试问的东西
    定时构建常用 设置
    jenkins 定时构建 位置
    jenkins 使用的python 不是指定的python 的解决方法
  • 原文地址:https://www.cnblogs.com/zhuzhudong/p/10840329.html
Copyright © 2011-2022 走看看