почему базовый указатель может указывать на производный объект только при публичном наследовании?

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

возможный дубликат общедоступного и частного наследования в C++   —  person g3nair    schedule 21.05.2013

См. также:  BitBucket Pipeline не может найти контейнер после ssh в DigitalOcean Droplet
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 3
  1. g3nair

    На самом деле указатель на базу может указывать на производный класс, даже если база является закрытой. Дело в том, что такое преобразование невозможно из вне класса. Однако такое преобразование по-прежнему возможно выполнить в контексте, когда база доступна.

    Пример:

    #include <iostream>
    using namespace std;
    
    struct Base
    {
        void foo() const {
            cout << "Base::foo()\n";
        }
    };
    
    struct Derived : private Base
    {
        const Base* get() const {
            return this; // This is fine
        }
    };
    
    int main()
    {
        Derived d;
        const Base *b = &d; // This is illegal
        const Base *b = d.get(); //This is fine
        b->foo();
    }
    

    Живой пример

    Живой пример с виртуальным вызовом

    @Энгью, понял! большое спасибо! но мне все же хотелось бы более глубокого понимания того, почему полиморфизм во время выполнения разрешен только при публичном наследовании. person g3nair; 21.05.2013

    @ g3nair Что вы имеете в виду под полиморфизмом во время выполнения? Вы имеете в виду преобразование производных в базовые? Если это так, причина в том, что открытое наследование представляет собой IS-A, в то время как защищенное/частное наследование обычно называется реализованным в терминах. person g3nair; 21.05.2013

    под полиморфизмом времени выполнения я имею в виду тот полиморфизм, который реализуется с использованием базового указателя и виртуальных функций. person g3nair; 21.05.2013

    @ g3nair g3nair Как я только что показал выше, он работает и с непубличным наследованием. person g3nair; 21.05.2013

    Вопрос оператора заключался в том, почему, а не в том, что действительно, а что нет. Есть ли какое-то обоснование для принятия такого решения? Объясняется ли это обоснованием в каких-либо стандартных документах С++ iso? person g3nair; 22.11.2019

  2. g3nair

    Если я прав, вы спрашиваете о видимости элементов внутри класса. Как вы сказали, public/protected/private повлияет на доступность ваших членов/функций членов/методов. (см. Разницу между частным, общедоступным и защищенным наследованием) Однако полиморфизм не ограничивается открытым наследованием.

    пример:

    class B
    {
        protected:
            virtual void do_B() = 0;
    };
    
    class A : protected B
    {
        virtual void do_B() {};
    };
    
  3. g3nair

    Вот пример, который поможет вам лучше понять

    class Base{
      public:
      int foo;
    };
    class Derived: private Base{
      public:
      int bar;
    };
    

    Теперь в этой программе давайте посмотрим, что может делать объект производного класса. Объект производного класса может

    • Публичный доступ к целочисленной переменной bar.
    • Доступ к целочисленной переменной foo осуществляется частным образом (только внутри класса Derived), поскольку отношение наследования является закрытым.

    Теперь давайте посмотрим, что произойдет, если указатель Base сможет сделать, если он будет указывать на такой объект. Для указателя базового класса

    • Указатель Base не может получить доступ к строке переменных, поскольку он указывает только на базовую часть объекта производного класса.
    • И в соответствии с указателем базового класса переменная foo является общедоступной, поскольку в базовом классе было определено, что она является общедоступной.

    Итак, теперь вы можете видеть двусмысленность, с которой столкнется базовый указатель, если он указывает на объект класса, унаследованного в частном отношении.

    Неоднозначность: в соответствии с производным классом объект foo является закрытым, но базовый указатель считает его общедоступным.

    Таким образом, мораль частного или защищенного наследования теряется, если такие вещи были разрешены. Надеюсь, это рассеет ваши сомнения.

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: