问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C++面向对象编程之继承详解

创作时间:
作者:
@小白创作中心

C++面向对象编程之继承详解

引用
CSDN
1.
https://blog.csdn.net/2302_80023639/article/details/141088443

C++中的继承机制是面向对象编程的核心特性之一,它允许一个类(派生类)继承另一个类(基类)的成员变量和成员函数。这种机制不仅能够减少代码冗余,还能实现代码的复用和扩展。本文将从继承的基本概念出发,详细讲解其语法格式、继承方式、隐藏机制、作用域、默认成员函数以及与友元、静态成员的关系等内容。

继承的概念

在现实生活中,继承通常指的是家里的财产或地位传给后代。而在C++中,继承则是一个类(派生类)从另一个类(基类)继承成员变量和成员函数的机制。例如,在一个外卖系统中,骑手、商家和用户都有一些共同的信息(如名字、地址等),通过继承,我们可以将这些共同信息定义在一个基类中,然后让各个派生类继承这个基类,从而避免代码冗余。

继承语法格式

C++中继承的语法格式如下:

class 子类: 继承方式  父类
{
    // 内容
};

例如:

class Person
{
public:
    void Print()
    {
        cout << _num << endl;
    }
protected:
    int _num = 0;
};

class Student : public Person
{
private:
    int _id = 3;
};

继承方式

继承方式分为公有(public)、保护(protected)和私有(private)三种。这三种继承方式决定了基类成员在派生类中的访问权限。具体来说:

  • 公有继承:基类的公有成员在派生类中保持公有,保护成员保持保护,私有成员保持私有。
  • 保护继承:基类的公有成员在派生类中变为保护,保护成员保持保护,私有成员保持私有。
  • 私有继承:基类的所有成员在派生类中都变为私有。

隐藏机制

当派生类和基类有同名成员时,会发生隐藏。隐藏机制决定了在派生类中,基类的同名成员将不可见。例如:

class Person
{
public:
    void Print()
    {
        cout << _num << endl;
    }
    int _num = 0;
};

class Student : public Person
{
public:
    int _id = 3;
    int _num = 3;
};

int main()
{
    Student s;
    cout << s._num << endl; // 输出子类的_num
    cout << s.Person::_num << endl; // 输出基类的_num
    return 0;
}

基类和派生类对象赋值转换

派生类对象可以赋值给基类对象,因为派生类包含了基类的所有成员。但是,基类对象不能赋值给派生类对象,因为基类缺少派生类特有的成员。

继承中的作用域

在继承中,派生类和基类是两个独立的作用域。如果派生类中有与基类同名的成员,那么在派生类中将隐藏基类的同名成员。

派生类的默认成员函数

在继承中,派生类需要处理构造函数、拷贝构造函数、赋值重载和析构函数。例如:

class Person
{
public:
    Person(const char* name = "peter") : _name(name) {}
    Person(const Person& p) : _name(p._name) {}
    Person& operator=(const Person& p)
    {
        if (this != &p)
            _name = p._name;
        return *this;
    }
    ~Person() {}
protected:
    string _name;
};

class Student : public Person
{
public:
    Student(const char* name = "Peter", int id = 0) : Person(name), _id(id) {}
    Student(const Student& s) : Person(s), _id(s._id) {}
    Student& operator=(const Student& s)
    {
        if (this != &s)
        {
            Person::operator=(s);
            _id = s._id;
        }
        return *this;
    }
private:
    int _id;
};

继承与友元

友元关系不能继承。即使一个类是另一个类的友元,它也不能访问继承链中其他类的私有成员。

继承与静态成员

静态成员属于整个继承链。例如,如果基类有一个静态成员变量,那么在派生类中访问这个变量时,实际上是在访问同一个变量。

菱形继承及菱形虚拟继承

菱形继承是指一个类从两个或多个基类继承相同的内容,这可能导致代码冗余和二义性问题。例如:

class job
{
public:
    int _name = 100;
};

class teacher : public job
{
};

class student : public job
{
};

class assistant : public student, public teacher
{
};

int main()
{
    assistant a;
    cout << a._name << endl; // 编译错误,二义性
    return 0;
}

为了解决这个问题,可以使用菱形虚拟继承:

class job
{
public:
    int _name = 100;
};

class Student : virtual public job
{
protected:
    int _num;
};

class Teacher : virtual public job
{
protected:
    int _id;
};

class Assistant : public Student, public Teacher
{
protected:
    string _majorCourse;
};

int main()
{
    Assistant a;
    cout << a._name << endl; // 正确
    return 0;
}

通过使用virtual关键字,可以确保在继承链中只有一份基类的内容,从而避免冗余和二义性问题。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号