Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
 Аватар для stikkas
20 / 20 / 8
Регистрация: 26.01.2014
Сообщений: 56

Доступ к приватному методу наследника через родителя

21.02.2014, 09:07. Показов 4635. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Тут натолкнулся на интересную штуку.
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
#include <iostream>
using namespace std;
 
class A {
public:
 
    virtual void f() {
        cout << "A.f" << endl;
    }
};
 
class B : public A {
 
    void f() {
        cout << "B.f" << endl;
    }
};
 
/*
 *
 */
int main(int argc, char** argv) {
    A *a = new B();
    a->f();
    //    B *b = new B();
    //    b->f();
    return 0;
}
есть какие-то доводы в пользу такого поведения?
Или это зависит от реализации? У меня a->f() выдает B.f , а b->f(), как и положено не компилируется.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.02.2014, 09:07
Ответы с готовыми решениями:

Доступ к приватному члену через нестатическую ссылку
Привет всем. забуксовал.. подтолкните пжалста: ситуация: - в хедере class A { private: int a; public: virtual void...

Доступ к приватному полю через адрес экземпляра объекта
Объясните такой момент class A { private: char s; public: char Get(){ return s; }

Нужно из класса наследника передать параметры в класс родителя
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; class ploskost{ protected: float d; int x1,y1,x2,y2; public: ...

14
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
21.02.2014, 09:15
Цитата Сообщение от stikkas Посмотреть сообщение
а b->f(), как и положено не компилируется.
А в какой секции вы объявили f() в классе В?
0
 Аватар для stikkas
20 / 20 / 8
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:23  [ТС]
а что не заметно?
по-умолчанию у class - private
у struct - public
Этот вопрос возник по аналогии с Java, там запрещено сужать область доступа для переопределяемых методов.
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
21.02.2014, 09:27
Вот и подумайте об этом.
А в остальном не вижу ни чего удивительного или я просто не понял вашего вопроса...
0
 Аватар для stikkas
20 / 20 / 8
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:30  [ТС]
Вопрос в том, что получается С++ допускает возможность вызова закрытого метода потомка через указатель на базовый класс.
0
320 / 225 / 74
Регистрация: 22.11.2013
Сообщений: 867
Записей в блоге: 1
21.02.2014, 09:34
Цитата Сообщение от stikkas Посмотреть сообщение
Или это зависит от реализации? У меня a->f() выдает B.f , а b->f(), как и положено не компилируется.
Ну правильно класс B наследник класса А, функция-член virtual void f() у него перегружаема и объявлена как public поэтому к ней и можно обратиться из main(). Но при таком обращении ей соответствует void f() класса B. Вот и Ваш ответ (т.е. она видна из класса А, но работает по процедуре класса B). А на прямую к ней не обратишься Вы сами пишите
Цитата Сообщение от stikkas Посмотреть сообщение
по-умолчанию у class - private
Но У Вас обращение к классу A...
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
21.02.2014, 09:43
Вы вызываете функцию f() посредством указателя на класс А где эта ф-я указана со спецификатором public. Однако так как эта функция виртуальная то вызываемая функция будет искаться по таблице виртуальных функций, а не как обращение к объекту класса В. Т.е. будет просто передан указатель на функцию f() из класса В.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
21.02.2014, 09:50
Цитата Сообщение от stikkas Посмотреть сообщение
Вопрос в том, что получается С++ допускает возможность вызова закрытого метода потомка через указатель на базовый класс.
да
если посмотришь на дизасемблированый код
то увидишь две таблицы виртуальных функций для класса A и для B
что то типа
Assembler
1
2
;A
offset  f_a;
Assembler
1
2
;B 
offset f_b;
имена я придумал свои, у каждого компилятора свое искажение имен
так в результате
Цитата Сообщение от stikkas Посмотреть сообщение
C++
1
2
A *a = new B();
   a->f();
идет обращение к таблице B
и вызывается f_b
и все в порядке на уровне исполнения
а уровень доступа это на этапе компиляции, в исполняемом коде уже нет ни publiс ни private

Добавлено через 2 минуты
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
0
320 / 225 / 74
Регистрация: 22.11.2013
Сообщений: 867
Записей в блоге: 1
21.02.2014, 09:50
Ilot,

Не по теме:

солидарность примите :)

0
 Аватар для stikkas
20 / 20 / 8
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 10:06  [ТС]
ValeryS,
Это я все прекрасно понимаю. Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
Вот и все.
А так можно сделать как в Python или Javascript - договориться, что то что начинается с подчеркивания - это закрытый (ну если очень хочется то обратиться и к нему напрямую).
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка. Такое поведение считается нормальным? (не с точки зрения техники выполнения кода, здесь все внорме).
Если да, то вопросов нет.
А если нет, то есть какие-то сложности отслеживания данных ситуаций на стадии компилирования?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.02.2014, 10:17
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
Обычно уровень видимости вообще не меняют. Какой смысл в открытии ранее закрытого метода? Так же не получится воспользоваться радостями полиморфизма (использовать базовый класс, где подразумевается производный). Если уж хочется запретить вызов виртуальной функции из базового класса, сделайте ее чистой (pure virtual).
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
21.02.2014, 10:45
Цитата Сообщение от Tulosba Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
простой пример
MFC класс CFormView метод Create для создания окна
зарыт
я делаю свой производный класс
как я должен создать окно?
переопределить метод и объявить его открытым
ты предлагаешь что то другое?
Цитата Сообщение от Tulosba Посмотреть сообщение
Если уж хочется запретить вызов виртуальной функции из базового класса,
речь идет о уже готовых библиотеках классов
Цитата Сообщение от stikkas Посмотреть сообщение
Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
компилятор делает код понятный процессору, а на уровне процессора пока нет закрытых функций
Цитата Сообщение от stikkas Посмотреть сообщение
А так можно сделать как в Python или Javascript
эти программы работают на виртуальных машинах, видать в них есть закрытые участки кода
Цитата Сообщение от stikkas Посмотреть сообщение
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка.
раз разрешили значит нормально смотрят, но это мое мнение
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.02.2014, 10:53
Лучший ответ Сообщение было отмечено stikkas как решение

Решение

Цитата Сообщение от stikkas Посмотреть сообщение
Такое поведение считается нормальным?
Такое поведение чем то сродни привязке параметра по умолчанию во время компиляции для виртуальных функций. Может быть Вы слышали выражение:
C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, it blows away your whole leg.
Сейчас правда речь не о сравнении C и C++, а о том, что в этих языках есть тонкие места, с которыми рано или поздно сталкивается любой разработчик. Надо их просто знать. И да, всё, что соответствует стандарту языка, считается нормальным.
C++11 §11.5
The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
И приведен практически Ваш пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class B {
public:
   virtual int f();
};
class D : public B {
private:
   int f();
};
void f() {
   D d;
   B* pb = &d;
   D* pd = &d;
   pb->f(); // OK: B::f() is public,
            // D::f() is invoked
   pd->f(); // error: D::f() is private
}
Добавлено через 8 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
речь идет о уже готовых библиотеках классов
Согласен. Но ты же не будешь отрицать, что:
Цитата Сообщение от Tulosba Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
2
 Аватар для stikkas
20 / 20 / 8
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 10:54  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do, it blows away your whole leg.
yeap, it's right
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
21.02.2014, 11:28
Цитата Сообщение от Tulosba Посмотреть сообщение
Но ты же не будешь отрицать, что:
не буду
но ООП в С++ имеет столько дырок
тот же MFC создал какой то свой ООП
и мое выражение
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот
относилось скорей к нему, чем например к Qt
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.02.2014, 11:28
Помогаю со студенческими работами здесь

Лишнее удаление родителя при создании класса наследника
Не могу понять откуда в выводе программы появляется первая надпись &quot;delete A&quot;. По идее надписей &quot;delete&quot; должно быть столько же,...

Как получить доступ к приватному полю
Всем доброго времени суток! Есть такое задание: нужно написать класс, который помимо всего прочего состоит из объекта еще одного класса, в...

Как избежать повтора параметров конструктора класса-родителя в конструкторе наследника?
С каждым новым наследуемом классом, число параметров конструктора увеличивается. class A { public: A(int a, float b, double c) ...

Указание родительскому методу брать данные конечного Наследника
Есть примерный такой код. Как указать чтобы родительский метод брал данные конечного наследника ? Чтобы не менять изначальную...

Почему извне есть доступ к приватному nested-классу?
class Test { struct PrivateType { PrivateType() {} }; public: void func(PrivateType) {} }; int main() {


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через 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-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru