zoukankan      html  css  js  c++  java
  • 浅谈 C++ 继承

    继承

    定义:继承就是新类从已有类那里得到已有的特性。类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类,产生的新类称为派生类或子类。

    继承可以扩展已存在的代码,目的也是为了代码重用,继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。其权限如下图所示:

    下面是一个时钟的例子。

    #include <iostream>
    using namespace std;
    
    class Clock
    {
    public:
        Clock(int h = 0, int m = 0, int s = 0) : hour(h), minute(m), second(s)
        {
            cout << "This is the Clock's constructor" << endl;
        }
    
        Clock(const Clock &other) : hour(other.hour), minute(other.minute), second(other.second)
        {
            cout << "This is the Clock's copy constructor" << endl;
        }
    
        ~Clock()
        {
            cout << "This is the Clock's destructor" << endl;
        }
    
        void showTime()
        {
            cout << hour << ":" << minute << ":" << second << endl;
        }
    
        void setTime(int h, int m, int s)
        {
            hour = h;
            minute = m;
            second = s;
        }
    
    private:
        int hour;
        int minute;
        int second;
    };
    
    class CalendarClock : public Clock
    {
    public:
        CalendarClock(int y, int M, int d, int h, int m, int s) : Clock(h, m, s), year(y), month(M), day(d)
        {
            cout << "This is the CalendarClock's constructor" << endl;
        }
    
        CalendarClock(const CalendarClock &other) : Clock(other), year(other.year), month(other.month), day(other.day)
        {
            cout << "This is the CalendarClock's copy constructor" << endl;
        }
    
        void show()
        {
            cout << year << "-" << month << "-" << day << " ";
            Clock::showTime();
        }
    
        void setTime(int y, int M, int d, int h, int m, int s)
        {
            Clock::setTime(h, m, s);
            year = y;
            month = M;
            day = d;
        }
    
        ~CalendarClock()
        {
            cout << "This is the CalendarClock's destructor" << endl;
        }
    
    private:
        int year;
        int month;
        int day;
    };
    
    int main(void)
    {
        CalendarClock c(2020,10,5,9,57,5);
        c.show();
        Clock *p = &c;
        p->showTime();
        system("pause");
        return 0;
    }
    

    虚基类

    为了解决多继承时的命名冲突和冗余数据问题,C++ 提出了虚继承,使得在派生类中只保留一份间接基类的成员。

    在继承方式前面加上 virtual 关键字就是虚继承。如果遇见sizeof,一个 virtual +4 ,然后去掉重复的部分。

    构造函数执行的流程为:
    1、传参
    2、执行直接或者间接虚基类构造
    3、执行直接基类构造
    4、为数据成员开辟空间
    5、执行构造函数函数体

    下面是一道考题:

    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
        Base(int i) { cout << i; }
       ~Base() { }
    };
    
    class Base1: virtual public Base
    {
    public:
        Base1(int i, int j = 0) : Base(j) { cout << i; }
       ~Base1() {}
    };
    
    class Base2: virtual public Base
    {
    public:
        Base2(int i, int j = 0) : Base(j) { cout << i; }
       ~Base2() {}
    };
    
    class Derived : public Base2, public Base1
    {
    public:
       Derived(int a, int b, int c, int d) : Base(a), Base2(d), Base1(c), mem2(b), mem1(a) { cout << b; }
    private:
       Base2 mem2;
       Base1 mem1;
    };
    
    int main(void)
    {
       Derived objD (1, 2, 3, 4);
    }
    

    仔细思考一下,先初始化虚基类,输出1;
    然后按“public Base2, public Base1”的顺序,先初始化Base2,再初始化Base1,输出43;
    再初始化mem2,输出02;接着初始化mem1,输出01;最后执行{}里的语句,输出2。

  • 相关阅读:
    第3章 MFC框架程序剖析
    第2章 掌握C++
    第1章 Windows程序内部运行机制
    【MFC】画线
    使用RegSetValueEx修改注册表时遇到的问题(转)
    读书笔记
    POJ 1182[并查集]
    读书笔记
    HihoCoder 1532 : 最美和弦
    HihoCode 1531 : 德国心脏病
  • 原文地址:https://www.cnblogs.com/wsl540/p/13771535.html
Copyright © 2011-2022 走看看