c++-繼承的學習

繼承的基本概念

  • 繼承和派生
    • 繼承概念
    • 派生類的訪問控制(繼承三種方式、類三種訪問控制、三看原則)綜合訓練
    • 繼承中的構造和析構
      • 類型兼容性原則
      • 繼承中的構造和析構
      • 繼承中同名成員函數、成員變量處理方法
      • 繼承中的static關鍵字
  • 繼承概念
  • 派生類的訪問控制(繼承三種方式、類三種訪問控制、三看原則)綜合訓練
  • 繼承中的構造和析構
    • 類型兼容性原則
    • 繼承中的構造和析構
    • 繼承中同名成員函數、成員變量處理方法
    • 繼承中的static關鍵字
  • 多繼承概念
  • 多繼承
    • 多繼承概念
    • 二義性
    • 虛繼承基本實驗原理
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>

using namespace std;


class Student
{
public:
    Student()
    {

    }
    Student(int id, string name)
    {
        this->id = id;
        this->name = name;
    }

    void printS() {
        cout << "id = " << this->id << ", name = " << this->name << endl;
    }
    int id;
    string name;
};

//建立一個新的學生類,增長score、功能
class Student2
{
public:
    Student2(int id, string name, int score)
    {
        this->id = id;
        this->name = name;
        this->score = score;
    }

    void printS() {
        cout << "id = " << this->id << ", name = " << this->name << endl;
        cout << "score = " << this->score << endl;
    }
private:
    int id;
    string name;

    //add
    int score;
};


//經過繼承建立一個新的學生類
class Student3 :public Student
{
public:
    Student3(int id, string name, int score) :Student(id, name)
    {

        this->score = score;
    }

    void printS() {
        Student::printS();
        cout << "score = " << this->score << endl;
    }
private:
    int score;
};


int main(void)
{
    Student3 s3(1, "zhang3", 80);

    s3.printS();


    return 0;
}

繼承的方式

  • 規則1, 只要是父類中的private成員,無論是什麼繼承方式,兒子都訪問不了
  • 規則2, 若是是公有(public)繼承, 兒子中的訪問控制權限保持不變。
  • 規則3, 若是是保護(protected)繼承, 兒子中父親中除了private成員,其他在兒子中都是protected
  • 規則4, 若是是私有(private)繼承, 兒子中的父親的除了private成員,其他在二中都是private成員。ios

  • 三看原則:
    • 看調用的成員變量是在類的內部仍是類的外部
    • 看兒子繼承方式,
    • 當前變量在兒子中的變量在父親中的訪問控制權限
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <memory>

using namespace std;



class Parent
{
public:
    int pub; //在類的內部 和 外部 都能訪問。
protected:
    int pro; //在類的內部能夠訪問, 在類的外部不能夠訪問
private:
    int pri;  //在類的內部能夠訪問, 在類的外部不能夠訪問
};

//公有繼承
class Child :public Parent
{
public:
    void func()
    {
        cout << pub << endl; //pub父類的public成員變量,在public繼承 類的 【內部 外部】能夠訪問。

        cout << pro << endl;//pro 是父類protected成員變量 在public繼承類的 【內部】能夠訪問。外部訪問不了 
                            //此時的pro在孫子可以訪問,說此時pro不是private成員,而是protected成員

        //cout << pri << endl; //pri 是父類private成員變量 在public繼承類的 【內部,外部】[不]能夠訪問。
    }

};

//孫子類
class SubChild : public Child
{
    void sub_func()
    {
        cout << pro << endl;
    }
};


//保護繼承
class Child2 :protected Parent
{
public:
    void func2() {
        pub;//此時pub經過protected繼承 可以在類的內部訪問。 
            //pub 在類的內部能夠訪問, 類的外部訪問不了, 類的兒子能夠訪問
            //pub 就是protected成員
        pro;//pro 根pub 是同樣的性質,pro也是protected成員
        //pri;
    }
};

class Sub_child2:public Child2
{
public:
    void sub_func2() {
        pub;
        pro;
    }
};

//私有繼承
class Child3 :private Parent
{
public:
    void func3()
    {
        pub;//pub 在類的內部能夠訪問。在類的內部能夠訪問,類的外部不能訪問。
            //pub 在兒子中訪問不了,說明pub在Child3中是 私有成員
        pro;//pro 根pub的性質是同樣, 也是私有成員。
        pri;
    }
};

class Sub_Child3 :public Child3
{
public:
    void sub_fun3()
    {
        pub;
        pro;
    }
};



int main(void)
{
    Child c1;
    c1.func();

    c1.pub;
    //c1.pri;

    //Child2 c2;
    //c2.pub;
    //c2.pro;
    
    Child3 c3;
    //c3.pub;
    //c3.pro;

    Child2 c2;
    c2.pub;
    c2.pro;

    c1.pub;
    

    return 0;
}

繼承方式的練習

#include     <iostream>
using namespace std;


class   A
{
private:
    int a;
protected:
    int b;
public:
    int c;
    A()
    {
        a = 0;
        b = 0;
        c = 0;
    }
    void    set(int a, int  b, int  c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
    }
};

class   B : public  A
{
public:
    void    print()
    {
        //cout << "a    =   " << a;              //a是父類的私有成員訪問不了
        cout << "b  =   " << b;              //b 此時是保護成員,類的內部能夠訪問
        cout << "c  =   "<<c << endl;           //c 此時是公有成員,類的內部能夠訪問
    }
};

class   C : protected   A
{
public:
    void    print()
    {
        //cout << "a    =   " << a;              //a是父類的私有成員訪問不了
        cout << "b  =   " << b;              //b 在子類中是protected權限,類的內部能夠訪問。
        cout << "c  =   " <<c << endl;   //c 子類的protected成員,類的內部能夠訪問。
    }
};

class   D : private A
{
public:
    void    print()
    {
        //cout << "a    =   " << a;                 //a是父類的私有成員訪問不了
        cout << "b  =   " << b << endl;      //b 此時是private成員,類的內部能夠訪問。
        cout << "c  =   " << c << endl;      //c 此時是private成員,類的內部能夠訪問。
    }
};

int main(void)
{
    A   aa;
    B   bb;
    C   cc;
    D   dd;
    aa.c = 100;                  //c 是公有 ,類的外部能夠訪問。
    bb.c = 100;                  //Bpublic 繼承與A ,保持權限不變,c 是公有, 類的外部能夠訪問
    //cc.c = 100;                    //C protected 繼承與A, c 在此類中是protected成員,類的外部不能訪問。
    //dd.c = 100;                    //D private 繼承與A, c在此類中private成員,類的外部不能訪問。
    aa.set(1, 2, 3);            //可否訪問???
    bb.set(10, 20, 30);         //可否訪問???
    //cc.set(40, 50, 60);           //可否訪問???
    //dd.set(70, 80, 90);           //可否訪問???

    bb.print();                  //print 是定義在B類 public成員函數,在類的外部能夠訪問。
    cc.print();                  //print 是定義在C類 public成員函數,在類的外部能夠訪問。
    dd.print();                  //print 是定義在D類 public成員函數,在類的外部能夠訪問。

    return 0;
}

類的兼容性複製原則

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

/*
    子類對象能夠看成父類對象使用。
    子類對象能夠直接賦值給父類對象。
    子類對象能夠直接初始化父類對象.
    ****父類指針能夠直接指向子類對象***
    父類引用能夠直接引用子類對象
*/

class Parent
{
public:
    void printP() {
        cout << "a " << this->a << endl;
    }
    int a=333;
};

class Child :public Parent
{
public:
    void printC()
    {
        cout << "b = " << this->b << endl;
    }
    int b;
};


void myPrint(Parent *pp)
{
    pp->printP();
}

int main(void)
{
//  Parent p;

//  Child c = p; //p對象填充不滿c對象空間,

//  Child c;

//  Parent p = c;//c 對象所佔用的內存空間 >= p對象佔用空間 可以填充滿p對象所須要空間。

//  p = c;

//  c.printP(); //c 可以當作父類 p 來使用。

    Parent *pp = NULL;//父類指針
    Child *cp = NULL;//子類指針
    

    Parent p;//父類對象
    Child c; //子類對象

    

    pp = &c;//c 內存佈局可以知足父類指針的所有需求, 能夠用一個兒子的對象地址給父類指針賦值。
    
    myPrint(&p);
    myPrint(&c);

    return 0;
}

子類的構造和析構

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

class Parent
{
public:
    Parent()
    {
        cout << "Parent().." << endl;
        a = 0;
    }
    Parent(int a) {
        cout << "Parent(int)..." << endl;
        this->a = a;
    }
    ~Parent(){
        cout << "~Parent" << endl;
    }
    int a;
};

class Child :public Parent
{
public:
    //在調用子類的構造函數時候,必定會調用父類的構造函數
    // 父類先構造,子類後構造。
    Child(int a, int b) :Parent(a)
    {
        cout << "Child(int, int)..." << endl;
        this->b = b;
    }

    void printC() {
        cout << "b = " << b << endl;
    }

    ~Child(){
        cout << "~Child()..." << endl;
    }

    int b;
};

int main(void)
{
    Child c(10, 20);

    c.printC();
    
    return 0;
}

子類與父類的變量名相同

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;


class Parent
{
public:
    Parent(int a) {
        this->a = a;
    }

    int a;
};

class Child :public Parent
{
public:
    Child(int p_a, int c_a) :Parent(p_a)
    {
        this->a = c_a;
    }

    void print()
    {
        cout << Parent::a << endl;
        cout << this->a << endl;//child's a
    }
    int a;
};


int main(void)
{
    Child c(10, 100);
    c.print();

    
    return 0;
}

繼承中的static

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

class A
{
public:
    static int a;
private:

};

class B :public A
{
public:
private:
};

int A::a = 100;//靜態成員變量 初始化

int main(void)
{
    A a1;
    A a2;

    cout << a1.a << endl;//100
    cout << a2.a << endl;//100

    A::a = 300;

    cout << a1.a << endl;//300
    cout << a2.a << endl;//300

    B b1;
    B b2;
    A::a = 400;

    cout << "------" << endl;
    cout << b1.a << endl;//400
    cout << b2.a << endl;//400
    cout << a1.a << endl;//400
    cout << a2.a << endl;//400

    return 0;
}

多繼承

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>


using namespace std;

//傢俱類
class Furniture
{
public:
    int m; //材質
};

//將父親類繼承爺爺類  改爲虛繼承, 防止兒子在多繼承個人時候,出現爺爺中的變量會拷貝多份。
class Bed:virtual public Furniture
{
public:
    void sleep() {
        cout << "在牀上睡覺" << endl;
    }
};


class Sofa:virtual public Furniture
{
public:
    void sit() {
        cout << "在沙發上休息" << endl;
    }
};

//沙發牀
class SofaBed :public Bed, public Sofa
{
public:
    void SleepAndSit() {
        sleep();
        sit();
    }
};

int main(void)
{
    Bed b;
    b.sleep();

    Sofa s;
    s.sit();

    cout << " ------ " << endl;

    SofaBed sb;
    sb.SleepAndSit();

    sb.m = 100;//此時只有一個m
    // sb.Bed::m = 100;
    // sb.Sofa::m = 200;
    
    return 0;
}
相關文章
相關標籤/搜索