c++-继承的学习

2019-12-22 16:00:54来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

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成员。

  • 三看原则:
    • 看调用的成员变量是在类的内部还是类的外部
    • 看儿子继承方式,
    • 当前变量在儿子中的变量在父亲中的访问控制权限
#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;
}

原文链接:https://www.cnblogs.com/ygjzs/p/12079008.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:返回指针的函数

下一篇:使用动态数组,按照城市名字拼音排序