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

Спецификаторы доступа и виртуальные функции - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
kotleta
 Аватар для kotleta
42 / 42 / 11
Регистрация: 13.09.2012
Сообщений: 196
17.09.2012, 18:28     Спецификаторы доступа и виртуальные функции #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
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
 
using namespace std;
 
class A
{
    public:
    int x;
 
    virtual void m()
    {
        cout << "A";
    }
};
 
class B: protected A
{
    public:
    void m()
    {
        cout << "B";
    }
};
 
int main()
{
    A o1, *pA = &o1;
    B o2, *pB = &o2;
 
    pA=&o2;
 
    pA->m();
 
    return 0;
}
Собственно в упор не понимаю, почему если ставить спецификатор public, то все ок
а если защищенные, то не работает..
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.09.2012, 18:28     Спецификаторы доступа и виртуальные функции
Посмотрите здесь:

C++ Виртуальные функции
C++ виртуальные функции
Вопрос про Спецификаторы доступа Public и Private C++
C++ виртуальные и чисто виртуальные функции
Спецификатор доступа и виртуальные функции C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
17.09.2012, 18:35     Спецификаторы доступа и виртуальные функции #2
Не public-наследование = пользователи B не должны знать, что B наследуется от A. Поэтому, естественно, B и не может изображать из себя A, но вызывать при этом свои виртуальные функции. Для пользователей B этот класс никак не связан с A.

Можно его связать с A только для наследников B, тогда это protected. Можно вообще только для себя: тогда private.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
17.09.2012, 18:36     Спецификаторы доступа и виртуальные функции #3
http://ru.wikipedia.org/wiki/%D0%9D%...D0%B5)#C.2B.2B
kotleta
 Аватар для kotleta
42 / 42 / 11
Регистрация: 13.09.2012
Сообщений: 196
17.09.2012, 19:13  [ТС]     Спецификаторы доступа и виртуальные функции #4
Да, я про спецификаторы доступа почитал

что если в базовом классе private, то наследование обрывается
если protected, то наследники имеют его элементы с доступом либо protected, private
если public, то с public, protected, private

~OhMyGodSoLong~, вообще непонятно, что вы написали))
скорее всего я просто плохо соображаю..

Что за пользователи?

Я просто не понимаю как связано то, что элементы класса А в производном классе B при protected будут классу B доступны, но не доступны при обращении из "внешнего мира"
И преобразование указателей производного класса к базовому классу

Jupiter, я уже там был

Одним из основных преимуществ public-наследования является то, что указатель на классы-наследники может быть неявно преобразован в указатель на базовый класс, то есть для примера выше можно написать:
Хорошо, элементы класса А при наследовании классу В передаются как "защищенные",
мы преобразовали указателю на базовый класс адрес производного и теперь А
ну теперь может видеть методы класса В

но почему если protected, то все нельзя. Ведь B наследует от А, это А поставил защищенность своих элементов для В, но не наоборот.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.09.2012, 19:23     Спецификаторы доступа и виртуальные функции #5
если класс B не публично наследуется от класса А, то факт наследования виден только внутри методов класса B (а также для друзей и при защищенном наследовании - для наследников класса B).
Вне класса B все выглядит так, будто B и не наследовался от класса A. Поэтому преобразования и не работают:
C++
1
2
3
4
5
6
7
8
int main()
{
    B b;
    A* aptr = &b;
    // вот этот код  не в методе класса B. значит тут все выглядит так,
    // будто класс B от А не наследовался. Поэтому такое преобразование
    // указателей недопустимо.
}
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
17.09.2012, 20:09     Спецификаторы доступа и виртуальные функции #6
Цитата Сообщение от kotleta Посмотреть сообщение
Что за пользователи?
Те, кто пишет new B();

Цитата Сообщение от kotleta Посмотреть сообщение
но почему если protected, то все нельзя. Ведь B наследует от А, это А поставил защищенность своих элементов для В, но не наоборот.
Именно: B наследует A. А вот эта штука вверху, которая после двоеточия и до A, показывает, какой спецификатор доступа будут иметь функции A, унаследованные B. Этим управляют оба класса.

Если там будет стоять что-то кроме public, то все функции A будут иметь спецификатор не выше protected, то есть объект, полученный через new B();, не имеет доступных методов A. Так как он не может "в нормальном режиме" изображать из себя A (иметь те же доступные public-методы, что и у A), то и привести его к типу A нельзя.
kotleta
 Аватар для kotleta
42 / 42 / 11
Регистрация: 13.09.2012
Сообщений: 196
18.09.2012, 12:45  [ТС]     Спецификаторы доступа и виртуальные функции #7
Понял
Если там будет стоять что-то кроме public, то все функции A будут иметь спецификатор не выше protected, то есть объект, полученный через new B();, не имеет доступных методов A.
Вот эта строчка ключевая
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
18.09.2012, 13:04     Спецификаторы доступа и виртуальные функции #8
Если там будет стоять что-то кроме public, то все функции A будут иметь спецификатор не выше protected, то есть объект, полученный через new B();, не имеет доступных методов A.
Вот эта строчка ключевая
Если придираться, то это не совсем верно.

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
////////////////////////////////////////////////////
пример 1
class A
{
protected:
  void F() {}
};
 
class B : public A
{
};
 
A* a = new B(); // это верно. B является A из-за публичного наследования
// не важно какие там спецификаторы у методов класса A
 
a->F(); // неверно, т.к. все методы у класса A защищенные
 
////////////////////////////////////////////////////
пример 2
 
class A
{
protected:
  void F() {}
};
 
class B : protected A
{
};
 
A* a = new B(); // ошибка. B не является A из-за защищенного наследования.
т.е. интерпретация спецификаторов у методов в базовом классе никак не изменяется.
публичное остается публичным, защищенное - защищенным и т.д. Один класс B перестает считаться
наследником класса A. Это несколько отличается от процитированного.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.09.2012, 17:33     Спецификаторы доступа и виртуальные функции
Еще ссылки по теме:

Виртуальные функции C++
Спецификаторы доступа при наследовании C++
Наследование, спецификаторы доступа C++

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

Или воспользуйтесь поиском по форуму:
Mr.X
Эксперт С++
 Аватар для Mr.X
2798 / 1574 / 246
Регистрация: 03.05.2010
Сообщений: 3,651
18.09.2012, 17:33     Спецификаторы доступа и виртуальные функции #9
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Те, кто пишет new B();

Именно: B наследует A. А вот эта штука вверху, которая после двоеточия и до A, показывает, какой спецификатор доступа будут иметь функции A, унаследованные B. Этим управляют оба класса.

Если там будет стоять что-то кроме public, то все функции A будут иметь спецификатор не выше protected, то есть объект, полученный через new B();, не имеет доступных методов A. Так как он не может "в нормальном режиме" изображать из себя A (иметь те же доступные public-методы, что и у A), то и привести его к типу A нельзя.
Если уж быть совсем точными, то при public-наследовании приведение к базовому классу допустимо в любых функциях, при protected-наследовании приведение к базовому protected-классу допустимо только в производном классе и его друзьях и его наследниках и друзьях наследников, а при private-наследовании - только в производном классе и его друзьях.
Yandex
Объявления
18.09.2012, 17:33     Спецификаторы доступа и виртуальные функции
Ответ Создать тему
Опции темы

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