C++学习笔记之 继承

继承

一个类继承另一个类,被继承的叫父类,另一个则是子类,子类可以继承、拓展、重写父类的方法

基本语法

class 子类:public 父类
{}

例:

#include <iostream>
#include <string>

using namespace std;

class A
{
public:
    void run()
    {
        about();
        cout << "A class is running..." << endl;
    }

    void about()
    {
        cout << "This is a class..." << endl;
    }
};

class B : public A
{
public:
    void run()
    {
        about();
        cout << "B class is running..." << endl;
    }
};

int main()
{
    A a;
    B b;
    a.run();
    b.run();
    return 0;
}
This is a class...
A class is running...
This is a class...
B class is running...

派生类

利用继承机制,新的类可以从已有的类中派生。那些用于派生的类称为这些特别派生出的类的“基类”

语法

class 派生类 : 继承方式 基类
{}

继承方式

父类中的构造和析构

#include <iostream>
#include <cstdio>
#define print(text) printf("--------------%s--------------\n",text)

using namespace std;

class Base
{
public:
    Base() {
        cout << "Base的默认构造函数调用" << endl;
    }

    ~Base() {
        cout << "Base的析构函数调用" << endl;
    }
};

class Other
{
public:
    Other() {
        cout << "Other的默认构造函数调用" << endl;
    }

    ~Other() {
        cout << "Other的析构函数调用" << endl;
    }
};

class Son : public Base
{
public:
    Son() {
        cout << "Son的默认构造函数调用" << endl;
    }

    ~Son() {
        cout << "Son的析构函数调用" << endl;
    }

    Other other;
};

class Base2
{
public:
    Base2(int a) {
        cout << "Base2的有参构造函数调用" << endl;
        this->m_A = a;
    }

    ~Base2() {
        cout << "Base2的析构函数调用" << endl;
    }
    
    int m_A;
};

class Son2 : public Base2
{
public:
    Son2(int a = 100):Base2(a) // 通过初始化列表,显示调用父类中的其他的构造函数
    {
        cout << "Son2的有参构造函数调用" << endl;
    }
    
    ~Son2() {
        cout << "Son2的析构函数调用" << endl;
    }
};

void test01() {
    print("test01");
    // Base b;
    Son s; // 当创建子类对象时,先调用父类构造函数,再调用其他类的构造函数,最后调用子类构造函数,析构函数相反
}

void test02() {
    print("test02");
    Son2 s = Son2(10);
    cout << s.m_A << endl;
}

int main() {
    test01();
    test02();
    print("end");

    return EXIT_SUCCESS;
}
--------------test01--------------
Base的默认构造函数调用
Other的默认构造函数调用
Son的默认构造函数调用
Son的析构函数调用
Other的析构函数调用
Base的析构函数调用
--------------test02--------------
Base2的有参构造函数调用
Son2的有参构造函数调用
10
Son2的析构函数调用
Base2的析构函数调用
--------------end--------------

同名成员

继承中的非静态同名成员处理

#include <iostream>
#include <cstdio>
#define print(text) printf("--------------%s--------------\n",text)

using namespace std;

class Base
{
public:
    int m_A;

    Base() {
        this->m_A = 10;
    }

    void run() {
        cout << "Base running..." << endl;
    }

    void run(int a) {
        cout << "Base running " << a << "..." << endl;
    }
};

class Son : public Base
{
public:
    Son() {
        this->m_A = 100;
    }

    void run() {
        cout << "Son running..." << endl;
    }
};

void test01() {
    print("test01");
    Son s;
    cout << "Son.m_A = " << s.m_A << endl;

    // 如果想访问父类中同名的非静态成员变量,需要加作用域
    cout << "Base.m_A = " << s.Base::m_A << endl;
}

void test02() {
    print("test02");
    Son s;
    s.run();
    s.Base::run(); // 如果想访问父类中同名的非静态成员函数,需要加作用域

    // 如果子类中出现了和父类同名的非静态成员函数,子类的成员函数会隐藏掉父类中所有的成员函数
    s.Base::run(2);
}

int main() {
    test01();
    test02();
    print("end");

    return EXIT_SUCCESS;
}
--------------test01--------------
Son.m_A = 100
Base.m_A = 100
--------------test02--------------
Son running...
Base running...
Base running 2...
--------------end--------------

继承中的静态同名成员处理

#include <iostream>
#include <cstdio>
#define print(text) printf("--------------%s--------------\n",text)

using namespace std;

class Base
{
public:
    // 共享同一个数据
    // 编译阶段分配内存
    // 类内声明,类外初始化
    static int m_A;

    static void run() {
        cout << "Base下的run调用" << endl;
    }

    static void run(int a) {
        cout << "Base下的run(int)调用" << endl;
    }
};
int Base::m_A = 10;

class Son : public Base
{
public:
    static int m_A;

    static void run() {
        cout << "Son下的run调用" << endl;
    }
};
int Son::m_A = 20;

void test01() {
    print("test01");

    // 通过对象访问
    Son s;
    cout << "Son m_A = " << s.m_A << endl;
    cout << "Base m_A = " << s.Base::m_A << endl;

    // 通过类名访问
    cout << "Son m_A = " << Son::m_A << endl;
    cout << "Base m_A = " << Son::Base::m_A << endl;
}

void test02() {
    print("test02");
    // 通过对象访问
    Son s;
    s.run();
    s.Base::run();
    s.Base::run(1);

    // 通过类名
    Son::run();
    Son::Base::run();
    Son::Base::run(1);
}

int main() {
    test01();
    test02();
    print("end");

    return EXIT_SUCCESS;
}
--------------test01--------------
Son m_A = 20
Base m_A = 10
Son m_A = 20
Base m_A = 10
--------------test02--------------
Son下的run调用
Base下的run调用
Base下的run(int)调用
Son下的run调用
Base下的run调用
Base下的run(int)调用
--------------end--------------

多继承

基本语法

class 子类 : 继承方式 父类1, 继承方式 父类2
{}

一般不建议使用多继承

posted @ 2020-12-05 20:20  小宇宙zjy  阅读(75)  评论(0编辑  收藏  举报