栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

(C++)继承与派生

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

(C++)继承与派生

目录

一、继承的概念和语法

1、继承

2、继承的语法

3、继承的权限

4、继承的对象内存模型

5、继承中的构造函数与析构函数

6、const修饰的成员函数

7、同名成员

8、继承中的static关键字

9、继承中的类型兼容性原则

二、多继承

1、多继承的概念

2、多继承的语法

3、多继承的二义性

4、虚继承

5、向上转型


一、继承的概念和语法

1、继承

继承可以理解为从一类向另一个类获取成员变量和成员函数的过程。

2、继承的语法

子类(派生类)继承父类(基类):

class 派生类名 :[继承方式] 基类名

{

        (继承并隐藏了基类的所有成员);

        派生类新增加的成员

}; 

#include 
#include 
using namespace std;

class Person          //父类或者基类
{
    protected:
        char m_name[32];
        int m_age;
    public:
        Person()
        {
            strcpy(m_name,"小明");
            m_age = 18;
        }
};

class Student:public Person   //子类或者派生类  public继承权限
{
    private:
        int m_id;
    public:
        Student(int id)
        {
            m_id = id;
        }
        void show()
        {
            cout<<"m_name:"< 

3、继承的权限

公有继承:

        基类的权限在派生类中不变,基类中的私有成员在派生类中不可访问。

保护继承:

        基类的公有成员在派生类中具有保护权限,其它不变,基类中的私有成员在派生类中不可访问。

私有继承:

        基类中所有的成员在派生类中都具有私有权限,基类中的私有成员在派生类中不可访问。

#include 
using namespace std;
class TestA
{
    private:
        int m_a;
    protected:
        int m_b;
    public:
        int m_c;
};

class TestB:private TestA  //私有继承
{
    
   public:
    void test()
    {
        //m_a++;  //基类中的私有成员变量,不可访问
        m_b++;
        m_c++;
    }
};

class TestC:protected TestA   //保护继承
{
    
   public:
    void test()
    {
        //m_a++;  //基类中的私有成员变量,不可访问
        m_b++;
        m_c++;
    }
};

class TestD:public TestA
{
    
   public:
    void test()
    {
        //m_a++;  //基类中的私有成员变量,不可访问
        m_b++;
        m_c++;
    }
};

int main(int argc, char const *argv[])
{
    TestB tb;
    tb.test();
    //tb.m_c;       //私有成员无法访问
    TestC tc;
    //tc.m_c = 1;   //保护的成员无法访问
    TestD td;
    td.m_c = 1;     //公有成员可以访问
    return 0;
}

4、继承的对象内存模型

继承先给基类分配空间,在给派生类分配空间。

#include 
using namespace std;
class Person
{
    public:
        int m_age;
};
class Student:public Person
{
    public:
        int m_id;
};
int main(int argc, char const *argv[])
{
    Student s1;    //继承先给基类分配空间,再给派生类分配空间
    cout< 

5、继承中的构造函数与析构函数

(1)继承中的构造函数

类的构造函数不能被继承,因为即使继承了,由于构造函数的名称与该类的名称也不相同,所以也就不存在构造函数了,所以也就不能调用基类的构造函数,为了初始化基类成员,需要在派生类的构造函数的初始化列表中,显示调用基类的构造函数。

(2)继承中的析构函数

析构函数同样不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个构造函数,编译器知道如何选择,无须程序员干涉。

析构函数的执行顺序和构造函数的执行顺序刚好相反。通常先执行派生类的析构函数,在执行基类的构造函数。

#include 
#include 
using namespace std;

class Person
{
    protected:
 
        char name[32];
        int age;
    public:

        Person(const char *n,int a)
        {
            cout<<"Person的有参构造函数"<year = y;
            this->month = m;
            this->day = d;  
        }
        ~Date()
        {
            cout<<"Date的析构函数"< 

6、const修饰的成员函数

常成员函数:普通函数声明后加上const关键字。函数只能访问常量

#include 
using namespace std;

class Student
{
    public:
        Student(char *name,int age,int score);
        char *getname() const;  
        int getage() const;
   
    private:
        char *m_name;
        int m_age;
        float m_score;
};

char* Student::getname() const  //成员函数必须声明和定义处都加上const
{
    return m_name;
}

int Student::getage() const
{
    //m_age++; 常成员函数修饰只读变量
    return m_age;
}

int main(int argc, char const *argv[])
{

    return 0;
}

7、同名成员

基类和派生类出现同名函数,默认调用派生类中的中的成员,基类成员函数被隐藏、

#include 
using namespace std;
class TestA
{
    private:
        int m_a;
    public:
        void show()
        {
            cout<<"this is TestA"< 

8、继承中的static关键字

如果基类中定义了静态成员,则该静态成员将所有的派生类共享。

#include 
using namespace std;

class A
{
    public:
        static int count;
    
    public:
        A()
        {
            count++;
        }
};

int A::count = 0;

class B:public A
{

};

int main(int argc, char const *argv[])
{   
    B b1;
    cout< 

9、继承中的类型兼容性原则

概念:在需要基类对象的地方,都可以使用公有派生类对象代替,通过公有继承,派生类得到了除基类中的构造函数,析构函数的所有成员,这样公有派生类可以解决基类能解决的问题

(1)子类对象可以当作父类来使用

(2)父类指针可以直接指向子类对象

(3)基类引用可以直接引用派生类对象

#include 
using namespace std;
class Parent
{
    protected:
        int m_a;
        int m_b;
    public:
        Parent()
        {
            cout<<"Parent的无参构造函数"<m_a = a;
            this->m_b = b;
        }
        void print()
        {
            cout<<"m_a = "<二、多继承 

1、多继承的概念

派生类中只继承一个基类,被称为单继承,继承多个基类,称为多继承

多继承容易让代码逻辑复杂,思维混乱,所以在Java,C#等已经取消了多继承

2、多继承的语法

多继承就是将继承的基类用逗号隔开即可。

#include 
using namespace std;
class AirPlane
{
    protected:
        int high;
    public:
        AirPlane()
        {
            cout<<"飞机的构造函数"< 

3、多继承的二义性

如下图中C与B同时都继承了A;而D同时继承了B与C,从而分不清D中的a来自何处。

#include 
using namespace std;
class TestA
{
    public:
        int a;
};
class TestB:public TestA
{
    public:
        int b;
};
class TestC:public TestA
{
    public:
        int c;
};
class TestD:public TestB,public TestC
{
    public:
        int d;
};
int main(int argc, char const *argv[])
{
    TestD d1;
    cout< 

4、虚继承

虚继承的目的是让某个类做出声明,承诺愿意永远共享他的基类。在这种机制下,不论虚基类在继承体系中出现多少次,在派生类中都只包含一份虚基类的成员

#include 
using namespace std;

class TestA  //虚基类
{
    public:
        int a;
};

class TestB:virtual public TestA
{
    public:
        int b;
};

class TestC:virtual public TestA
{
    public:
        int c;
};

class TestD:public TestB,public TestC
{
    public:
        int d;
};

int main(int argc, char const *argv[])
{
    TestB tb;
    cout< 

5、向上转型

因为派生类不但继承了基类的成员,还添加了自己独有的成员,所以其内存大小必然大于基类。所以只能将派生类对象赋值给基类对象,派生类引用赋值给基类引用,派生类指针赋值给基类指针。

#include 
using namespace std;
class Parent
{
    private:
        int m_a;
};
class Child:public Parent
{
    private:
        int m_b;
};
int main(int argc, char const *argv[])
{
    int a = 1.11; 
    double b = 2;


    Parent p;
    Child c;
    p = c;    //只能将派生类对象赋值给基类对象,派生类引用赋值给基类引用,派生类指针赋值给基类指针
    ///c = p;
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928110.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号