Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
#1

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

21.02.2014, 09:07. Просмотров 839. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2014, 09:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Доступ к приватному методу наследника через родителя (C++):

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

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

Нужно из класса наследника передать параметры в класс родителя - C++
#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: ...

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

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

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

14
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:15 #2
Цитата Сообщение от stikkas Посмотреть сообщение
а b->f(), как и положено не компилируется.
А в какой секции вы объявили f() в классе В?
0
stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:23  [ТС] #3
а что не заметно?
по-умолчанию у class - private
у struct - public
Этот вопрос возник по аналогии с Java, там запрещено сужать область доступа для переопределяемых методов.
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:27 #4
Вот и подумайте об этом.
А в остальном не вижу ни чего удивительного или я просто не понял вашего вопроса...
0
stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 09:30  [ТС] #5
Вопрос в том, что получается С++ допускает возможность вызова закрытого метода потомка через указатель на базовый класс.
0
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...
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
21.02.2014, 09:43 #7
Вы вызываете функцию f() посредством указателя на класс А где эта ф-я указана со спецификатором public. Однако так как эта функция виртуальная то вызываемая функция будет искаться по таблице виртуальных функций, а не как обращение к объекту класса В. Т.е. будет просто передан указатель на функцию f() из класса В.
0
ValeryS
Модератор
6707 / 5116 / 482
Регистрация: 14.02.2011
Сообщений: 17,190
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 минуты
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
0
mustimur
268 / 222 / 57
Регистрация: 22.11.2013
Сообщений: 832
Записей в блоге: 1
21.02.2014, 09:50 #9
Ilot,

Не по теме:

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

0
stikkas
19 / 19 / 6
Регистрация: 26.01.2014
Сообщений: 56
21.02.2014, 10:06  [ТС] #10
ValeryS,
Это я все прекрасно понимаю. Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
Вот и все.
А так можно сделать как в Python или Javascript - договориться, что то что начинается с подчеркивания - это закрытый (ну если очень хочется то обратиться и к нему напрямую).
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка. Такое поведение считается нормальным? (не с точки зрения техники выполнения кода, здесь все внорме).
Если да, то вопросов нет.
А если нет, то есть какие-то сложности отслеживания данных ситуаций на стадии компилирования?
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
21.02.2014, 10:17 #11
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот закрытый метод родительского класса открывают в классе наследнике
Обычно уровень видимости вообще не меняют. Какой смысл в открытии ранее закрытого метода? Так же не получится воспользоваться радостями полиморфизма (использовать базовый класс, где подразумевается производный). Если уж хочется запретить вызов виртуальной функции из базового класса, сделайте ее чистой (pure virtual).
0
ValeryS
Модератор
6707 / 5116 / 482
Регистрация: 14.02.2011
Сообщений: 17,190
21.02.2014, 10:45 #12
Цитата Сообщение от Tulosba Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
простой пример
MFC класс CFormView метод Create для создания окна
зарыт
я делаю свой производный класс
как я должен создать окно?
переопределить метод и объявить его открытым
ты предлагаешь что то другое?
Цитата Сообщение от Tulosba Посмотреть сообщение
Если уж хочется запретить вызов виртуальной функции из базового класса,
речь идет о уже готовых библиотеках классов
Цитата Сообщение от stikkas Посмотреть сообщение
Просто с логической точки зрения запрещенный метод должен быть с любой стороны запрещенным (я так думаю, не берем в расчет доступы по указателям и смещениям);
компилятор делает код понятный процессору, а на уровне процессора пока нет закрытых функций
Цитата Сообщение от stikkas Посмотреть сообщение
А так можно сделать как в Python или Javascript
эти программы работают на виртуальных машинах, видать в них есть закрытые участки кода
Цитата Сообщение от stikkas Посмотреть сообщение
Вопрос заключался в том, может кто знает, как на такую ситуацию смотрят создатели языка.
раз разрешили значит нормально смотрят, но это мое мнение
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
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 Посмотреть сообщение
Обычно уровень видимости вообще не меняют.
2
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
0
ValeryS
Модератор
6707 / 5116 / 482
Регистрация: 14.02.2011
Сообщений: 17,190
21.02.2014, 11:28 #15
Цитата Сообщение от Tulosba Посмотреть сообщение
Но ты же не будешь отрицать, что:
не буду
но ООП в С++ имеет столько дырок
тот же MFC создал какой то свой ООП
и мое выражение
Цитата Сообщение от ValeryS Посмотреть сообщение
обычно делают наоборот
относилось скорей к нему, чем например к Qt
0
21.02.2014, 11:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.02.2014, 11:28
Привет! Вот еще темы с ответами:

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

Правда, что указатель класса-наследника не может указывать на объект класса-родителя? - C++
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Управление объектом наследника через базовый класс - C++
Даны два класса. Класс A - базовый класс, B - класс наследник. В классе А 3 поля, в наследнике - еще 2. Указателю на класс A присвоим...

Сравнение класса наследника через конструктор с одним аргументом - C++
#include &lt;iostream&gt; using namespace std; //////////////////////////////// class Counter { protected: unsigned int count; ...


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

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

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