1. 程式人生 > 實用技巧 >C++學習筆記之 繼承

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
{}

一般不建議使用多繼承