Обмен технологиями

C: Разница между композицией и наследованием

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Введение в композицию и сравнение с наследованием

что такое комбинация
(1) Композиция означает использование объектов нескольких других классов в качестве членов внутри класса.
(2) Используйте дерево классов для объяснения случаев.
(3) Комбинация также является методом повторного использования кода, суть которого заключается вСоставВключать

#include <iostream>
#include <vector>
#include <string>

// Leaf 类
class Leaf {
public:
    Leaf(const std::string& color) : color_(color) {
        std::cout << "Leaf constructor called: " << color_ << std::endl;
    }

    ~Leaf() {
        std::cout << "Leaf destructor called: " << color_ << std::endl;
    }

    void display() const {
        std::cout << "Leaf color: " << color_ << std::endl;
    }

private:
    std::string color_;
};

// Branch 类
class Branch {
public:
    Branch(int length) : length_(length) {
        std::cout << "Branch constructor called: " << length_ << " cm" << std::endl;
    }

    ~Branch() {
        std::cout << "Branch destructor called: " << length_ << " cm" << std::endl;
    }

    void display() const {
        std::cout << "Branch length: " << length_ << " cm" << std::endl;
    }

private:
    int length_;
};

// Tree 类,包含 Leaf 和 Branch 对象
class Tree {
public:
    Tree(const std::string& leafColor, int branchLength) 
        : leaf_(leafColor), branch_(branchLength) {
        std::cout << "Tree constructor called" << std::endl;
    }

    ~Tree() {
        std::cout << "Tree destructor called" << std::endl;
    }

    void display() const {
        leaf_.display();
        branch_.display();
    }

private:
    Leaf leaf_;
    Branch branch_;
};

int main() {
    Tree tree("Green", 150);
    tree.display();
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

Вставьте сюда описание изображения

Сравнение характеристик наследования и композиции
(1) Наследование — это своего рода (является а) Отношения транзитивны и не симметричны.
(2) Комбинация – это отношение части (имеет а),
(3) Наследование — это повторное использование «белого ящика». Поскольку наследование классов позволяет нам переопределять детали реализации родительского класса в соответствии с нашей собственной реализацией, реализация родительского класса видна дочернему классу.
(4) Функция повторного использования наследования «белого ящика» в определенной степени разрушает функцию инкапсуляции класса, поскольку она раскрывает детали реализации родительского класса подклассу.
(5) Комбинация относится к повторному использованию черного ящика.Внутренние детали содержащегося объекта невидимы для внешнего мира, поэтому его инкапсуляция относительно хороша, а взаимозависимость в реализации относительно невелика.
(6) Включенный в комбинацию класс будет создаваться и уничтожаться по мере создания содержащего его класса. Комбинации относятся к повторному использованию «черного ящика» и могут динамически определяться во время выполнения путем получения других ссылок на объекты или указателей того же типа. Недостатком является то, что в системе слишком много объектов.
(7) Принцип объектно-ориентированного проектирования заключается в том, чтобы сначала объединить, а затем наследовать.

Множественное наследование и его проблемы неоднозначности

множественное наследование
(1) Множественное наследование означает, что подкласс имеет несколько родительских классов.
(2)Демонстрация множественного наследования
(3) Нет очевидной разницы между принципами множественного наследования и одиночного наследования.
(4) Множественное наследование может привести к проблемам неоднозначности.
Неоднозначность множественного наследования 1
(1) Сценарий: C имеет множественное наследование от A и B, поэтому при вызове членов с одинаковыми именами A и B в C может возникнуть неоднозначность.
(2) Причина: C наследует член с тем же именем (другой домен пространства имен) от A и B, поэтому при вызове объекта C компилятор не может определить, какой из них мы хотим вызвать.
(3) Решение 1. Во избежание возникновения подобных ситуаций не допускайте повторного конфликта имен публичных представителей A и B. Но иногда это неконтролируемо.
(4) Решение 2. Четко укажите, какой из них вызывать при кодировании, используйте cA::func(), чтобы четко указать, что вызывается функция класса A вместо функции класса B.
(5) Решение 3. Переопределите функцию в C, тогда будет вызвана функция в C, а функция в A и B будет скрыта.
(6) Резюме: Эту проблему можно решить, но хорошего решения не существует.

Неоднозначность множественного наследования 2
(1) Сценарий: проблема наследования алмазов.То есть A — это класс-предок, B1:A, B2:A, C:B1,B2. В настоящее время при использовании объекта C для вызова метода в A может возникнуть неоднозначность.
(2) Анализ: c.func() неоднозначен, cA::func() также неоднозначен, но c.B1::func() и c.B2::func() не являются неоднозначными.
(3) Решение: то же, что и проблема 1, но проблема 2 более тонкая, и ее труднее избежать.

Вставьте сюда описание изображения

// 祖类
class Aa {
 public:
  void show() { std::cout << "A's method" << std::endl; }
};

// 派生类 B1 和 B2,从 A 继承
class B1 : public Aa {
 public:
  void show() { std::cout << "B1's show" << std::endl; }
  void showB1() { std::cout << "B1's method" << std::endl; }
};

class B2 : public Aa {
 public:
  void show() { std::cout << "B2's show" << std::endl; }
  void showB2() { std::cout << "B2's method" << std::endl; }
};

// 派生类 C,从 B1 和 B2 继承
class C : public B1, public B2 {
 public:
  void showC() { std::cout << "C's method" << std::endl; }
};

int test070103() {
  C c;
  // c.Aa::show();    // 调用 A 的方法 不可以
  c.Aa::B1::show();  // 调用 A 的方法 不可以
  c.B2::Aa::show();  // 调用 A 的方法 不可以
  c.B1::show();      // 调用 B1 的方法
  c.B2::show();      // 调用 B2 的方法
  c.showB1();        // 调用 B1 的方法
  c.showB2();        // 调用 B2 的方法
  c.showC();         // 调用 C 的方法
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

Виртуальное наследование решает проблему неоднозначности наследования алмазов.

Как использовать виртуальное наследование
(1) Сценарий: Алмазное наследование приводит к проблемам неоднозначности. По сути, в B1 и B2 содержатся два объекта-внука C, поэтому существует неоднозначность.
(2) Решение по виртуальному наследованию: пусть B1 и B2 виртуально наследуют A, и тогда C сможет нормально наследовать B1 и B2.
(3) Виртуальное наследование настолько просто. Оно создано для решения проблемы неоднозначности наследования алмазов. Оно не имеет прямого отношения к виртуальным функциям (для достижения полиморфных функций).

Принцип реализации виртуального наследования
(1) Принцип виртуального наследования: указатель таблицы виртуальных базовых классов vbptr и виртуальная таблица таблицы виртуальных базовых классов.
(2)Ссылка:https://blog.csdn.net/xiejingfa/article/details/48028491

Вставьте сюда описание изображения

Подведем итог

Поймите, что такое комбинация. В классе класса есть много переменных-членов других типов.
Понять разницу между композицией и наследованием
Неоднозначность: если вы выполняете функцию, она не обязательно может быть той, которую вы хотите указать.
Решение. Используйте cA::func(), чтобы явно указать вызываемый класс.
Виртуальное наследование немного похоже на условную компиляцию. Его нужно вводить только один раз. Для достижения эффекта внедрения его не нужно вводить повторно.

Записи об исследованиях и контакты, сообщающие о нарушениях, будут удалены.
Источник: Класс Интернета вещей учителя Чжу.