Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 19.04.2016
Сообщений: 8

Наследование. Не могу понять элементарную вещь

23.07.2019, 15:33. Показов 1213. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Допустим есть родительский класс и производный. Сейчас мы не затрагиваем полиморфизм.
Так или иначе присвоение указателю базового класса адреса объекта производного класса должно быть возможным. А не понимаю я следующее.:
Почему для такого присвоения производный класс обязательно должен наследоваться как public или protected?
Вот простой пример (без смысловой нагрузки, задача просто скомпилированть):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Based {
     int val;
public:
     Based(int v) : val(v) { }
};
 
class Derived : public Based {
     int val;
public:
      Derived(int v) : val(v), Based(v) { }
};
 
int main() {
       Based *ptr;
       Derived obj(5);
       ptr = &obj;
        return 0;
}
Зачем здесь обязательно public или protected наследование? Почему не компилируется с private?
Ведь операция присваивания выполняется для указателя и затрагивает только адреса.
Какие из скрытых методов (или перегруженных операторов) должны быть выполнены и не могу этого сделать из-за private наследования?
По-моему никакие, ведь мы имеем дело с указателем, а не самим объектом. А в чем тогда причина?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.07.2019, 15:33
Ответы с готовыми решениями:

Объясните умственно отсталому как сделать элементарную вещь в списке
Добрый день, спасибо что зашли в эту тему. Сколько я ни пытался лазить по разным сайтам, темам, я никак не могу понять как этим списком...

Не могу понять виртуальное наследование
Непонятны несколько моментов. Как строятся таблицы виртуальных классов? Есть базовый класс, У него два предка. А еще есть третий...

Наследование класов. Не могу понять в чем ошибка
Не могу понять где ошибка. Задание:Написать программу, в которой создается иерархия классов. Определить в классах необходимые конструктор и...

7
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
23.07.2019, 15:52
Цитата Сообщение от Ingeniger Посмотреть сообщение
Регистрация: 19.04.2016
Сообщений: 1
...
0
0 / 0 / 0
Регистрация: 19.04.2016
Сообщений: 8
23.07.2019, 16:03  [ТС]
Ну, да. Давно регистрировался, чтоб ссылки работали. Ничего не постил.
0
96 / 82 / 22
Регистрация: 19.10.2013
Сообщений: 485
23.07.2019, 16:37
Причина в том, что вы не можете вызывать приватные методы родительского класса. А конструктор - это тоже метод.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Based
{
    void method() {}
    
public:
    Based() {}
};
 
class Derived : public Based
{
public:
    Derived() 
        : Based()
    {
        method(); // ошибка: 'void Based::method()' is private within this context
    }
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Based
{
    Based() {}
};
 
class Derived : public Based
{
public:
    Derived() 
        : Based() // ошибка: 'Based::Based()' is private within this context
    { 
    }
};
Добавлено через 19 минут
Кажется я вопрос по диагонали прочитал, теперь понял, но объяснить не могу
Если Based будет унаследован приватно, то разумеется его производные не могут быть кастануты в Based, он же приватный =) это как пытаться достать сметану из банки с неизвестным содержимым, сметаны там может и не быть. А почему банка непрозрачная? А потому что так задумали производители. и если вы наследуете приватно класс, значит делаете это из каких-то конкретных соображений. Например, чтобы нельзя было случайно вызвать методы базового класса

C++
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
class Based
{
public:
     Based() {}
 
     void method()
     {
         std::cout << "Based" << std::endl;
     }
};
 
class Derived : public Based
{
public:
      Derived() : Based() {}
 
      void method()
      {
          std::cout << "Derived" << std::endl;
      }
};
 
int main(int argc, char *argv[])
{
    Based *ptr;
    Derived obj;
    obj.method();  // выведет Derived
 
    ptr = static_cast<Based*>(&obj);
    ptr->method(); // выведет Based
 
    return 0;
}
Вообще все эти private/public/protected - это сахар исключительно для программиста, скомпилированной программе всё равно какой доступ был к методам и переменным, она просто обращается к ним по адресам.
0
0 / 0 / 0
Регистрация: 19.04.2016
Сообщений: 8
23.07.2019, 16:38  [ТС]
WxMaper, такие простые вещи я вроде как знаю, я немного не об этом, есть нюанс.
Этот код компилируется:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Based {
     int val;
public:
     Based(int v) : val(v) { }
};
 
class Derived : Based {
     int val;
public:
      Derived(int v) : val(v), Based(v) { }
};
 
int main() {
       Based *ptr;
       Derived obj(5);
  //     ptr = &obj;
        return 0;
}
Если раскомментировать строку с присвомением указателю ptr адреса объекта obj уже нет. Прошу заметить, что в данном случае наследование уже private. Скрытый конструктор базового класса задействуется в строке определения объекта obj:
C++
1
     Derived obj(5);
При этом если отсутствует строка
C++
1
      ptr = &obj;
Код компилируется. Отсюда вопросы:почему компилируется код с приватным конструктором базового класса?
И почему присваивание указателю адреса делает код некомпилируемым? Ведь в случае с указателями ни конструкторы, ни перегруженные операторы присваивания для класса Based, не выполняются, т.к. мы имеем дело с адресами, а не самими объектами.
0
96 / 82 / 22
Регистрация: 19.10.2013
Сообщений: 485
23.07.2019, 16:43
Цитата Сообщение от Ingeniger Посмотреть сообщение
такие простые вещи я вроде как знаю, я немного не об этом, есть нюанс.
Я выше дополнил ответ, изначально не так понял ваш вопрос.
0
0 / 0 / 0
Регистрация: 19.04.2016
Сообщений: 8
23.07.2019, 17:03  [ТС]
Цитата Сообщение от Ingeniger Посмотреть сообщение
почему компилируется код с приватным конструктором базового класса?
Первый вопрос я зря написал, тут и так понятно.
Несмотря на то, что класс наследуется приватно, через строку инициализации производного класса мы лишь передаем параметр в базовый класс, а сам конструктор базового класса выполняется в своем (базовом классе), поэтому
определение объекта.
C++
1
 Derived obj(5)
возможно, несмотря на приватное наследование.
Цитата Сообщение от Ingeniger Посмотреть сообщение
И почему присваивание указателю адреса делает код некомпилируемым?
Вот это я изначально не понимал, почему производные не могут быть "кастануты" в Based, но после разъяснений WxMaper, вроде дошло. но если будут еще комментарии по этому, буду благодарен.
Спасибо.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
25.07.2019, 09:57
Цитата Сообщение от Ingeniger Посмотреть сообщение
Почему не компилируется с private?
Причина не техническая (технически это можно сделать с помощью c-style cast) - причина идеологическая.
Все дело в том, какое отношение между классами задает то или иное наследование.

* Приватное наследование обозначает отношение "реализован посредством".
Например: автомобиль реализован посредством колес (естественно не только, но это пример, который должен быть понятен всем, даже непрограммистам).

* Публичное наследование обозначает отношение "является разновидностью".
Например: ГАЗ-13 «Чайка» является разновидностью автомобиля.

Когда вы кастите указатель, вы применяете реализованное отношение к объектам. Т.е., если совсем буквально, то своим кастом к базовому вы говорите: газ-13 - это автомобиль.
Но вы не можете сказать, "автомобиль - это колесо", потому, что это не так.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.07.2019, 09:57
Помогаю со студенческими работами здесь

Не могу понять, в чем ошибка. Наследование классов
Начал изучать наследование классов и и &quot;затормозил&quot; на такой простенькой программе. Не могу понять в чем ошибка. #include...

Стек на основе массива структур - эт как понять читаю литературу и не могу понять!
Стек статически (на основе массива структур). Пример структура &quot;Товар&quot; которая включает в себя: № по каталогу(ключ), Название, цена, срок...

Не могу понять одну вещь в ряде Лорана
Кольца аналитичности | z | &lt; 1, 1 &lt; | z | &lt; 3, | z | &gt; 3. Раскладываем дробь на элементарные дроби: и вот он камень преткновения: ...

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

не могу догнать одну вещь
Задача: На вход программы подаются сведения о результатах соревнований по школьному многоборью. Многоборье состоит из соревнований по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru