С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
1

В производном классе вызов приватного метода базового класса

19.06.2016, 23:42. Просмотров 979. Ответов 32
Метки нет (Все метки)

Добрый вечер. Помогите понять одну вещь.
Имеется такое наследование:
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
class test1
{
public:
    void pubF()
    {
        privF();
    }
private:
    void privF()
    {
        cout<<this<<endl;
    }
};
 
class test2 : public test1
{
 
};
 
int main(int argc, char *argv[])
{
    test1 t1;
    test2 t2;
    t1.pubF();
    t2.pubF();
Выводятся разные адреса. Как так получается, ведь реализация функции pubF() по умолчанию для производного класса вызывает приватную функцию базового класса, и она спокойной вызывается? Почему так происходит, разве не должно быть ошибки доступа к функции privF() у объекта t2?
Спасибо!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.06.2016, 23:42
Ответы с готовыми решениями:

Почему при переопределении виртуального метода в производном классе выводится метод базового?
Всем добра! Помогите разобраться почему при переопределении виртуального...

Вызов функций базового класса в производном
Читаю книгу Харви М. Дейтел, Пол Дж. Дейтел - &quot;Как программировать на C++&quot;....

Как сделать компоненты базового класса доступными в производном классе, но недоступными вне классов?
Как сделать компоненты базового класса доступными в производном классе, но...

Почему при множественном наследовании в производном классе оказывется несколько экземпляров общего базового класса
Я не очень хорошо знаю плюсы, но я разбираюсь. Учусь, и мне хотелось бы иногда...

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

32
1Вирт1
168 / 192 / 48
Регистрация: 25.08.2011
Сообщений: 793
Завершенные тесты: 5
19.06.2016, 23:52 2
нет не должно вы вызываете открытую функцию член
1
Renji
2125 / 1563 / 476
Регистрация: 05.06.2014
Сообщений: 4,544
20.06.2016, 00:02 3
Цитата Сообщение от NewBi Посмотреть сообщение
Почему так происходит, разве не должно быть ошибки доступа к функции privF() у объекта t2?
Ну вас же не удивляет когда вам брать колбасу с витрины не разрешают (приватный метод), но продавец (публичный метод) может взять эту колбасу и продать вам. Здесь тот же принцип.
2
rikimaru2013
C++ Game Dev
2473 / 1141 / 349
Регистрация: 30.11.2013
Сообщений: 3,709
20.06.2016, 00:04 4
Renji, даже я не понял аллегории
0
Renji
2125 / 1563 / 476
Регистрация: 05.06.2014
Сообщений: 4,544
20.06.2016, 00:08 5
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Renji, даже я не понял аллегории
Есть объект "колбасный магазин". У магазина есть публичный метод "дать продавцу бабок и получить колбасу". Продавец при этом вызывает приватный метод "взять колбасу с витрины/склада/где там она у него лежит". А покупатель напрямую этот метод вызывать не может - посодют за воровство колбасы.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 00:29 6
Цитата Сообщение от NewBi Посмотреть сообщение
разве не должно быть ошибки доступа к функции privF() у объекта t2?
Не должно. Это потому, что у t2 нет доступа к privF(). У него есть доступ к pubF(). А то что Вы в pubF() вызываете privF() это Ваше право и компилятор не против. Вообще, открытые методы и нужны для доступа к чему-нибудь закрытому. К открытому и без них можно достучаться. Зато открытые могут ограничить доступ. Например, pubF() может не запускать privF() в обеденное время. Казалось бы, - странно: как-раз очень хочется колбасы, а не дают. Но продавец тоже должен обедать, а он когда обедает, колбасы ни за что не отдаст. Даже за деньги.
1
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
20.06.2016, 00:39  [ТС] 7
Я понимаю что вызываю public функцию( pubF() ), это да. Но как объект test2 может вызывать приватную функцию объекта test1? Ведь если реализацию не указывать, она будет по-умолчанию, а именно для класса test2 она должна выглядеть следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class test2 : public test1
{
public:
    void pubF()
    {
        privF();  // вот если явно так писать, то не получится даже скомпилировать.
    }
private:
    void privF()
    {
        cout<<this<<endl;
    }
};
Или реализация методов при передаче по-умолчанию выглядит не так как реализация базовых методов ???
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 00:44 8
Цитата Сообщение от NewBi Посмотреть сообщение
Но как объект test2 может вызывать приватную функцию объекта test1?
Не может и не вызывает. Хотя t2 это t1 только расширенный. Если явно реализовать то что Вы пишете это будет переопределение. Оно перекроет метод базового класса в производном.
1
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
20.06.2016, 00:54  [ТС] 9
Цитата Сообщение от IGPIGP Посмотреть сообщение
Не может и не вызывает.
Но выводятся два разных адреса, объекта test1 (в котором этот метод есть), и адрес объекта test2 ( в котором по идеи быть не должно этого метода). Не могу просто суть уловить эту.
Вот даже так пишу:
C++
1
2
3
4
5
test1 t1;
    test2 t2;
    cout<<&t1<<&t2;   //0x28fe2f 0x28fe2e
    t1.pubF(); //0x28fe2f
    t2.pubF(); //0x28fe2e
t2 как-то вызывает эту функцию значит?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 01:05 10
Цитата Сообщение от NewBi Посмотреть сообщение
Но выводятся два разных адреса,
Это нормально. Два разных объекта даже одного класса test1 будут иметь разные адреса. А метод у них один. Он не принадлежит экземпляру.
1
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
20.06.2016, 01:19  [ТС] 11
Цитата Сообщение от IGPIGP Посмотреть сообщение
Два разных объекта даже одного класса test1
Это тоже ясно, что разные объекты, соответственно разные адреса, у каждого объекта свой адрес. Просто ведь объект класса test2 тоже значит вызывает эту функцию ( privF() ). Реализация функции такова, что нужно просто вывести адрес объекта.
Когда эта функция вызывается для объекта test1, вопросов нет, она реализована в классе test1, и так как она приватна, то ее вызываю через публичную функцию. Но когда эта функция вызывается для объекта test2, то не понятно как это работает? Ведь эта функция( privF() ) при наследовании не может передаться, а каким тогда образом она вызывается ?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 01:24 12
Цитата Сообщение от NewBi Посмотреть сообщение
Ведь эта функция при наследовании не может передаться
Не просто может, а "передаётся". Я поставил кавычки потому, что "передаётся" не применимо к ситуации когда оно остаётся там же, где и было. Ещё раз. Наследник содержит в себе родителя как подмножество. В этом смысле всё не так как в жизни. Но ему ничего не нужно получать. Оно всё у него есть.
1
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
20.06.2016, 01:35  [ТС] 13
IGPIGP, а при наследовании, все методы которые унаследует производный класс, реализация эти методов будет выглядеть в производном классе также, как реализация методов в базовом классе ? Или там имеются какие-то дополнения? Ну вот на этом примере, при наследовании метода pubF() в классе test2, реализация будет так же выглядеть ? т.е.
C++
1
2
3
4
void pubF()
    {
        privF();
    }
Или будет что-то изменено?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 01:50 14
Цитата Сообщение от NewBi Посмотреть сообщение
будет выглядеть
Почему будет? Невиртуальный метод базового класса является методом и наследника. Он не передаётся и не перереализуется. Тут нет процесса механического перехода "из рук в руки".
Вообще, сказать что логика наследования выглядит слегка необычно было бы неправильно. Слово "слегка" слишком слабое определение. С одной стороны, наследник это надможество. Но как область видимости он похож на вложенную область, то есть повторное определение приводит к затенению внешнего.
Попытка представить это схематически, поначалу вызывает ассоциацию со сферическим вакуумом внутри коня, который охватывает этот вакуум своей наружной поверхностью. Иначе говоря, несколько наизнанку всё.
1
Renji
2125 / 1563 / 476
Регистрация: 05.06.2014
Сообщений: 4,544
20.06.2016, 02:01 15
Цитата Сообщение от NewBi Посмотреть сообщение
IGPIGP, а при наследовании, все методы которые унаследует производный класс, реализация эти методов будет выглядеть в производном классе также, как реализация методов в базовом классе ?
Базовый класс - солдат без меча. Производный класс - солдат с мечом. Вопрос: метод "пробежать три круга вокруг казармы" у них различается? А если на солдата еще противогаз надеть?

Производный класс, это базовый + свистелки и перделки. Разумеется, добавление свистелок на унаследованные методы не влияет никак. Ну, если свистелка не сводится к переопределению базового метода ("а теперь бегай на четвереньках, чтоб врагу попасть сложней было").
1
NewBi
1 / 1 / 0
Регистрация: 20.04.2015
Сообщений: 73
20.06.2016, 02:03  [ТС] 16
IGPIGP, получается в классе наследнике нету никакой "базовой" реализации наследуемого метода? А когда вызывается метод базового класса из объекта класса наследника, то вызывается реализация базового метода, как бы из внутреннего указателя на базовый класс ? Так что ли? Я просто думал, что за кулисами при наследовании методов базового класса, в реализацию этих методов в производном классе передается такая же реализация, и в итоге получается что-то вроде двух одинаковых реализаций в разных класса.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7092 / 3394 / 461
Регистрация: 04.12.2011
Сообщений: 9,446
Записей в блоге: 5
20.06.2016, 02:10 17
Цитата Сообщение от NewBi Посмотреть сообщение
производном классе передается такая же реализация
Нет передачи.
Цитата Сообщение от NewBi Посмотреть сообщение
А когда вызывается метод базового класса из объекта класса наследника, то вызывается реализация базового метода, как бы из внутреннего указателя на базовый класс ?
У них один и тот же метод. Он принадлежит классу (т.е. обоим классам). Указатель есть у обоих и в нём один и тот же адрес.
Речь идёт не о виртуальных методах, конечно. То есть метод принадлежит наследнику не меньше чем базовому. Поэтому лучше говорить, что он свой метод вызывает. Тогда не будет подобных вопросов.
1
rikimaru2013
20.06.2016, 02:11
  #18

Не по теме:

IGPIGP, а вы то куда со своей колбасой :wall: )))

0
IGPIGP
20.06.2016, 02:21
  #19

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
IGPIGP, а вы то куда со своей колбасой
Дык это же не моя. Это достояние мировой кулинарии. А я поначалу не узнал Вас под тегом противогаза[офф] rikimaru2013. Богатым будете.

0
rikimaru2013
20.06.2016, 02:22     В производном классе вызов приватного метода базового класса
  #20

Не по теме:

IGPIGP, :cry: как не узнали? Но мы же с первого класса вместе ...

0
20.06.2016, 02:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.06.2016, 02:22
Привет! Вот еще темы с ответами:

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

Вызов переопределенного метода из методов базового класса
Здравствуйте, у меня есть два класса, базовый и производный. В производном...

Вызов виртуального метода базового класса из указателя производного
Допустим есть такой код: #include &lt;iostream&gt; class Base { public:...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru