Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
stikkas
 Аватар для stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:07     Доступ к приватному методу наследника через родителя #1
Тут натолкнулся на интересную штуку.
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(), как и положено не компилируется.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:15     Доступ к приватному методу наследника через родителя #2
Цитата Сообщение от stikkas Посмотреть сообщение
а b->f(), как и положено не компилируется.
А в какой секции вы объявили f() в классе В?
stikkas
 Аватар для stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:23  [ТС]     Доступ к приватному методу наследника через родителя #3
а что не заметно?
по-умолчанию у class - private
у struct - public
Этот вопрос возник по аналогии с Java, там запрещено сужать область доступа для переопределяемых методов.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:27     Доступ к приватному методу наследника через родителя #4
Вот и подумайте об этом.
А в остальном не вижу ни чего удивительного или я просто не понял вашего вопроса...
stikkas
 Аватар для stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:30  [ТС]     Доступ к приватному методу наследника через родителя #5
Вопрос в том, что получается С++ допускает возможность вызова закрытого метода потомка через указатель на базовый класс.
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
21.02.2014, 09:34     Доступ к приватному методу наследника через родителя #6
Цитата Сообщение от stikkas Посмотреть сообщение
Или это зависит от реализации? У меня a->f() выдает B.f , а b->f(), как и положено не компилируется.
Ну правильно класс B наследник класса А, функция-член virtual void f() у него перегружаема и объявлена как public поэтому к ней и можно обратиться из main(). Но при таком обращении ей соответствует void f() класса B. Вот и Ваш ответ (т.е. она видна из класса А, но работает по процедуре класса B). А на прямую к ней не обратишься Вы сами пишите
Цитата Сообщение от stikkas Посмотреть сообщение
по-умолчанию у class - private
Но У Вас обращение к классу A...
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:43     Доступ к приватному методу наследника через родителя #7
Вы вызываете функцию f() посредством указателя на класс А где эта ф-я указана со спецификатором public. Однако так как эта функция виртуальная то вызываемая функция будет искаться по таблице виртуальных функций, а не как обращение к объекту класса В. Т.е. будет просто передан указатель на функцию f() из класса В.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
21.02.2014, 09:50     Доступ к приватному методу наследника через родителя #8
Цитата Сообщение от 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 минуты
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
21.02.2014, 09:50     Доступ к приватному методу наследника через родителя #9
Ilot,

Не по теме:

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

stikkas
 Аватар для stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 10:06  [ТС]     Доступ к приватному методу наследника через родителя #10
ValeryS,
Это я все прекрасно понимаю. Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
Вот и все.
А так можно сделать как в Python или Javascript - договориться, что то что начинается с подчеркивания - это закрытый (ну если очень хочется то обратиться и к нему напрямую).
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка. Такое поведение считается нормальным? (не с точки зрения техники выполнения кода, здесь все внорме).
Если да, то вопросов нет.
А если нет, то есть какие-то сложности отслеживания данных ситуаций на стадии компилирования?
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
21.02.2014, 10:17     Доступ к приватному методу наследника через родителя #11
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
Обычно уровень видимости вообще не меняют. Какой смысл в открытии ранее закрытого метода? Так же не получится воспользоваться радостями полиморфизма (использовать базовый класс, где подразумевается производный). Если уж хочется запретить вызов виртуальной функции из базового класса, сделайте ее чистой (pure virtual).
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
21.02.2014, 10:45     Доступ к приватному методу наследника через родителя #12
Цитата Сообщение от Tulosba Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
простой пример
MFC класс CFormView метод Create для создания окна
зарыт
я делаю свой производный класс
как я должен создать окно?
переопределить метод и объявить его открытым
ты предлагаешь что то другое?
Цитата Сообщение от Tulosba Посмотреть сообщение
Если уж хочется запретить вызов виртуальной функции из базового класса,
речь идет о уже готовых библиотеках классов
Цитата Сообщение от stikkas Посмотреть сообщение
Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
компилятор делает код понятный процессору, а на уровне процессора пока нет закрытых функций
Цитата Сообщение от stikkas Посмотреть сообщение
А так можно сделать как в Python или Javascript
эти программы работают на виртуальных машинах, видать в них есть закрытые участки кода
Цитата Сообщение от stikkas Посмотреть сообщение
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка.
раз разрешили значит нормально смотрят, но это мое мнение
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
21.02.2014, 10:53     Доступ к приватному методу наследника через родителя #13
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от 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 Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
stikkas
 Аватар для stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 10:54  [ТС]     Доступ к приватному методу наследника через родителя #14
Цитата Сообщение от 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.02.2014, 11:28     Доступ к приватному методу наследника через родителя
Еще ссылки по теме:

C++ Сравнение класса наследника через конструктор с одним аргументом
Нужно из класса наследника передать параметры в класс родителя C++
Указание родительскому методу брать данные конечного Наследника C++

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

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
21.02.2014, 11:28     Доступ к приватному методу наследника через родителя #15
Цитата Сообщение от Tulosba Посмотреть сообщение
Но ты же не будешь отрицать, что:
не буду
но ООП в С++ имеет столько дырок
тот же MFC создал какой то свой ООП
и мое выражение
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот
относилось скорей к нему, чем например к Qt
Yandex
Объявления
21.02.2014, 11:28     Доступ к приватному методу наследника через родителя
Ответ Создать тему
Опции темы

Текущее время: 00:52. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru