继承的详解

简介: 继承的详解

继承基础

继承得好处:减少重复代码
语法:

class 子类 : 继承方式 父类
子类也称为:派生类
父类也称为:基类

eg:

#include
using namespace std;
//公共部分
class BasePage
{
    
public:
    void test()
    {
    
        cout << "java,C++,Python" << endl;
    }
};
//继承
class java : public BasePage
{
    
public:
    void content()
    {
    
        cout << "java学科视频" << endl;
    }
};
int main()
{
    
    java a;
    a.test();
    a.content();
}

继承方式

1.公共继承
2.保护继承
3.私有继承
原理图:
在这里插入图片描述

继承中的对象模型

问题:从父类继承过来的成员,哪些属于子类对象中?
案例分析:

#include
using namespace std;
class base
{
    
public:
    int m_a;
protected:
    int m_b;
private:
    int m_c;
};
class son:public base
{
    
public:
    int m_d;
};
int main()
{
    
    son a;
    cout << sizeof(a) << endl;
}

执行结果:
16
结论:
父类中所有非静态成员属性都会被子类继承下去。
父类中的私有成员属性是被编译器给隐藏了,因此是访问不到的,但确实被继承下去了。

继承中构造和析构顺序

子类继承父类后,当创建子类对象,也会调用父类的构造函数
问题:
父类和子类的构造和析构顺序是谁先谁后?
实例:

#include
using namespace std;
class base
{
    
public:
    base()
    {
    
        cout << "base的构造函数" << endl;
    }
    ~base()
    {
    
        cout << "base的析构函数" << endl;
    }
};
class son:private base
{
    
public:
    son()
    {
    
        cout << "son的构造函数" << endl;
    }
    ~son()
    {
    
        cout << "son的析构函数" << endl;
    }

public:
    int m_d;
};
int main()
{
    
    son a;
}

执行结果:
在这里插入图片描述
结论:
继承中的构造和析构顺序如下:
先构造父类,再构造子类,
先析构子类,再析构父类。

继承同名成员处理方式

问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
1.访问子类同名成员,直接访问即可
2.访问父类同名成员,需要加作用域
eg:
1.同名成员属性

#include
using namespace std;
class base
{
    
public:
    int m_a;
    base()
    {
    
        m_a = 100;
    }
};
class son :public base
{
    
public:
    int m_b;
    son()
    {
    
        m_a = 200;
    }
};
int main()
{
    
    son a;
    cout << a.m_a << endl;//访问子类中的成员
    cout << a.base::m_a << endl;//访问父类中的成员
}

2.同名成员函数

#include
using namespace std;
class base
{
    
public:
    void func()
    {
    
        cout << "调用base下的func函数" << endl;
    }
};
class son :public base
{
    
public:
    void func()
    {
    
        cout << "调用son下的func函数" << endl;
    }
    
};
int main()
{
    
    son a;
    a.func();//访问子类中的成员
    a.base::func();//访问父类中的成员
}

注意事项:
如果子类中出现了和父类同名的成员函数,子类的同名函数成员回隐藏掉父类中所有同名成员函数
如果想访问到父类中被隐藏的同名成员函数,需要加作用域。

继承同名静态成员处理方式

问题:继承中同名的静态成员在子类对象上如何进行访问?
静态成员和非静态成员出现同名,处理方式一致
1.访问子类同名成员,直接访问即可
2.访问父类同名成员,需要加作用域
eg:
1.同名的静态成员属性

#include
using namespace std;
class base
{
    
public:
    static int m_a;
};
int base::m_a = 200;
class son:public base
{
    
public:
    static int m_a;
};
int son::m_a = 100;
int main()
{
    
    son a;
    //1.通过对象访问
    cout << "son下的m_a = " << a.m_a << endl;
    cout << "base下的m_a = " << a.base::m_a << endl;
    //2.通过类名访问
    cout << "son下的m_a = " << son::m_a << endl;
    cout<<"base下的m_a = "<<son::base::m_a<<endl;
    //解析:第一个::代表通过类名的方式访问   第二个::代表访问父类作用域下的m_a
}

2.同名的静态成员函数

#include
using namespace std;
class base
{
    
public:
    static int m_a;
    static void func()
    {
    
        cout << "base" << endl;
    }
};
int base::m_a = 200;
class son:public base
{
    
public:
    static int m_a;
    static void func()
    {
    
        cout << "son" << endl;
    }
};
int son::m_a = 100;
int main()
{
    
    son a;
    //1.通过对象访问
    a.func();
    a.base::func();
    //2.通过类名访问
    son::func();
    son::base::func();
    //解析:第一个::代表通过类名的方式访问   第二个::代表访问父类作用域下的func()
}

注意事项:
如果子类中出现了和父类同名的静态成员函数,子类的同名函数成员回隐藏掉父类中所有同名成员函数
如果想访问到父类中被隐藏的同名静态成员函数,需要加作用域。

多继承语法

C++允许一个类继承多个类
语法:

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

多继承可能会引发父类中有同名成员函数出现,需要加作用域区分
注意:
C++实际开发中不建议用多继承

#include
using namespace std;
class base1
{
    
public:
    int m_a;
    base1()
    {
    
        m_a = 100;
    }
};
class base2
{
    
public:
    int m_b;
    base2()
    {
    
        m_b = 100;
    }
};
class son: public base1,public base2
{
    
public:
    int m_c;
};

菱形继承

菱形继承概念:
两个派生类继承同一个基类
又有某个类同时继承两个派生类
这种继承称为菱形继承,或者钻石继承
图示:
在这里插入图片描述
问题:
1.两个派生类都会有基类的数据,会产生二义性
2.子类会继承两份来自动物的数据,其实并不需要
解决方法:
利用虚继承可以解决菱形继承的问题
即:在继承之前加上关键字virtual 变为虚继承
eg:

#include
using namespace std;
class A
{
    
public:
    int m_age;
};
class B:virtual public A{
    };
class C :virtual public A {
    };
class D : public B, public C{
    };
int main()
{
    
    D a;
    a.A::m_age = 1;
    a.B::m_age = 2;
    a.C::m_age = 3;
    cout << a.m_age << endl;
}
相关文章
|
4月前
|
程序员 C++
|
4月前
|
C++
c++继承
c++继承
39 0
|
4月前
|
Java C# C++
继承
继承
45 0
|
4月前
|
安全 Java 编译器
C++:继承
C++:继承
45 0
|
3月前
|
编译器 C++
C++中的继承
C++中的继承
32 1
|
4月前
|
安全 程序员 C++
C++之继承<1>【详解】
C++之继承<1>【详解】
|
11月前
|
存储 编译器 程序员
c++【继承】
C++ 继承,包括继承的概念和用法,菱形继承的产生,组合的介绍等丰富知识点,详细讲解,干货满满!
36 4
c++【继承】
|
10月前
|
程序员 编译器 C++
|
11月前
|
安全 编译器 程序员
|
11月前
|
Java C++