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

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

23.07.2019, 15:33. Показов 1189. Ответов 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru