Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Модели наследования в C++: множественное, многоуровневое, иерархическое

Модели наследования в C++: множественное, многоуровневое, иерархическое

В этом руководстве мы рассмотрим паттерны наследования в C++ — множественное, многоуровневое и иерархическое — с практическими примерами кода.

Наследование — фундаментальная возможность ООП. Она позволяет создавать новые классы, наследующие свойства и поведение существующих.

Ниже мы разберём три ключевые модели наследования в C++.


Многоуровневое наследование в C++

В многоуровневой иерархии класс наследуется от другого производного класса. Цепочка продолжается до достижения базового класса.

class A { // Реализация базового класса };
class B : public A { // B наследуется от A };
class C : public B { // C наследуется от B };

Здесь B наследуется от A, а C — от B, образуя вертикальную цепочку наследования.

Пример 1: Многоуровневое наследование в C++

#include <iostream>
using namespace std;

class A {
public:
    void display() {
        cout << "Base class content." << endl;
    }
};

class B : public A {};

class C : public B {};

int main() {
    C obj;
    obj.display();
    return 0;
}

Вывод

Base class content.

Программа показывает, что объект C может вызвать display(), определённый в конечном базовом классе A, так как ни B, ни C не переопределяют его. Компилятор ищет реализацию по цепочке наследования от наиболее производного класса вверх.


Множественное наследование в C++

C++ позволяет классу наследоваться от более чем одного базового класса. Например, Bat (летучая мышь) может наследоваться от Mammal (млекопитающее) и WingedAnimal (крылатое животное), так как летучая мышь — и млекопитающее, и крылатое существо.

Модели наследования в C++: множественное, многоуровневое, иерархическое

Пример 2: Множественное наследование в C++

#include <iostream>
using namespace std;

class Mammal {
public:
    Mammal() {
        cout << "Mammals can give direct birth." << endl;
    }
};

class WingedAnimal {
public:
    WingedAnimal() {
        cout << "Winged animals can flap." << endl;
    }
};

class Bat : public Mammal, public WingedAnimal {};

int main() {
    Bat b1;
    return 0;
}

Вывод

Mammals can give direct birth.
Winged animals can flap.

Разрешение неоднозначности при множественном наследовании

Когда два базовых класса предоставляют функцию с одинаковым именем, компилятор не может решить, какую вызвать — возникает ошибка неоднозначности.

class Base1 {
public:
    void someFunction() { /* ... */ }
};

class Base2 {
public:
    void someFunction() { /* ... */ }
};

class Derived : public Base1, public Base2 {};

int main() {
    Derived obj;
    // obj.someFunction(); // Ошибка: ambiguous
}

Используйте оператор разрешения области видимости для указания нужной функции базового класса:

int main() {
    Derived obj;
    obj.Base1::someFunction(); // Вызывает реализацию Base1
    obj.Base2::someFunction(); // Вызывает реализацию Base2
}

Иерархическое наследование в C++

В иерархическом наследовании несколько производных классов наследуются от одного базового. Все общие атрибуты и поведение инкапсулируются в базовом классе, а каждый производный добавляет свою специализацию.

Примеры: Physics, Chemistry, Biology наследуются от Science; Dog, Cat, Horse — от Animal.

Синтаксис иерархического наследования

class BaseClass { // Содержимое базового класса };
class DerivedOne : public BaseClass { // Дополнительные члены };
class DerivedTwo : public BaseClass { // Дополнительные члены };
class DerivedThree : public BaseClass { // Дополнительные члены };

Пример 3: Иерархическое наследование в C++

// C++ программа, демонстрирующая иерархическое наследование
#include <iostream>
using namespace std;

// Базовый класс
class Animal {
public:
    void info() {
        cout << "I am an animal." << endl;
    }
};

// Производный класс 1
class Dog : public Animal {
public:
    void bark() {
        cout << "I am a Dog. Woof woof." << endl;
    }
};

// Производный класс 2
class Cat : public Animal {
public:
    void meow() {
        cout << "I am a Cat. Meow." << endl;
    }
};

int main() {
    // Экземпляр Dog
    Dog dog1;
    cout << "Dog Class:" << endl;
    dog1.info();
    dog1.bark();
    
    // Экземпляр Cat
    Cat cat1;
    cout << "\nCat Class:" << endl;
    cat1.info();
    cat1.meow();
    return 0;
}

Вывод

Dog Class:
I am an animal.
I am a Dog. Woof woof.

Cat Class:
I am an animal.
I am a Cat. Meow.

И Dog, и Cat наследуют метод info() от Animal, в то время как каждый класс вводит своё специализированное поведение.

Сравнение моделей наследования

МодельСтруктураПримерОсобенности
МногоуровневоеA → B → CAnimal → Mammal → DogЦепочка специализаций
МножественноеA, B → CMammal, WingedAnimal → BatКомбинирование независимых интерфейсов, риск ромбовидной проблемы
ИерархическоеA → B, C, DAnimal → Dog, Cat, HorseОбщий базовый интерфейс, специализация в листьях

Ромбовидная проблема и виртуальное наследование

При множественном наследовании, если два базовых класса наследуются от общего предка, возникает дублирование подобъекта предка. Решение — виртуальное наследование:

class Base { /* ... */ };
class Derived1 : virtual public Base { /* ... */ };
class Derived2 : virtual public Base { /* ... */ };
class Final : public Derived1, public Derived2 { /* ... */ };

Ключевое слово virtual при наследовании гарантирует наличие только одного экземпляра Base в Final.

Язык C

  1. Классы и объекты в C#: Фундаменты надёжного ООП
  2. Абстрактные классы и методы в C#: практическое руководство
  3. Частичные классы и методы в C#: понимание и применение
  4. Sealed-классы и sealed-методы в C#: когда использовать, примеры и повышение безопасности кода
  5. Классы и объекты в C++: практическое руководство по объектно-ориентированному программированию
  6. Публичное, защищённое и приватное наследование в C++: подробный разбор
  7. Дружественные функции и классы в C++: мастерство контроля доступа
  8. C++ Struct vs Class: ключевые отличия, синтаксис и лучшие сценарии использования
  9. Классы хранения в C++: область видимости, время жизни и использование
  10. Полное руководство по дате и времени в C++