-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
1

Уровни доступа в производных классах

13.06.2018, 21:33. Показов 2211. Ответов 26
Метки нет (Все метки)

В одном учебнике прочел вот такую фразу: УРОВЕНЬ ДОСТУПА К ЧЛЕНАМ БАЗОВОГО КЛАССА МОЖЕТ БЫТЬ ИЗМЕНЕН В ПРОИЗВОДНОМ КЛАССЕ, НО ТОЛЬКО В СТОРОНУ УЖЕСТОЧЕНИЯ.

Немного поэксперементировал и оказалось, что это не совсем так.
Самому кажется странным, что если в базовом классе какая-то функция определена как protected, то в производном классе она может быть сделана public.
А вообще как на данный момент обстоят с этим дела?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.06.2018, 21:33
Ответы с готовыми решениями:

Переменная базового класса в производных классах
Есть абстрактный базовый класс и в нем определена переменная variable: class Base { public: ...

В производных классах перегрузить заданные операции
Нужна помощь с перегрузкой, я в ней не особо шарю. В общем есть такой код : #include <iostream>...

Реализация чистых виртуальных методов в производных классах
Здравствуйте! Интересует такой вопрос: Допустим, имеется у нас базовый абстрактный класс и...

Виртуальные функции (нужно ли во всех производных классах писать слово virtual?)
Нужно ли во всех производных классах писать слово virtual? Или достаточно только один раз в...

26
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 21:39 2
Цитата Сообщение от Просто Саша Посмотреть сообщение
Самому кажется странным, что если в базовом классе какая-то функция определена как protected, то в производном классе она может быть сделана public.
Просто Саша, это как же? Желательно с примером.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:14  [ТС] 3
Да пожалуйста, вот пример:

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
class Base
{
public:
    Base(int x) : b {x}
    {
    }
    auto func(int x) -> void
    {
        b += x;
    }
protected:
    auto print() -> void
    {
        cout << "Base class value: " << b << endl;
    }
private:
    int b;
};
 
class Derived : public Base
{
public:
    using Base::print;
    Derived(int x, int y) : Base {x}, d {y}
    {
    }
private:
    
    int d;
};
Добавлено через 26 минут
Грубо говоря, вопрос стоит так, как что-то унаследовать из базового класса, НО НЕ ПЕРЕОПРЕДЕЛИТЬ, а изменить только уровень доступа.

Я не совсем понимаю, как это делается.
Как это делается корректно?
Есть ли какие-либо правила?
И какова история изменения этих правил?

Вот мне пока кажется, что имеет место следующая схема:
1) Если что-то в базовом классе определяется в разделах public и protected, то в производном классе эти сущности могут быть как public, так и private и protected.
2) Если в базовом классе что-то определяется с уровнем private, то в производном классе оно может быть только private.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 22:16 4
C++
1
using Base::print;
А зачем вы так пишете? Этой строкой вы и даете фактически доступ пользователям класса Derived, предоставленный от Base. Если не писать эту строку, все будет нормально.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:19  [ТС] 5
Цитата Сообщение от QuakerRUS Посмотреть сообщение
А зачем вы так пишете?
Это не ответ.

Добавлено через 1 минуту
Переопределять уровни доступа в производных классах можно.
Вопрос в другом, когда это следует делать.
Но я не такой вопрос задавал, поскольку прежде чем разбираться, когда это корректно, а когда нет, надо знать, хотя бы как это делать. Я, честно говорю, не знаю, как это делать правильно.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 22:22 6
Просто Саша, почему не ответ? Вашему классу предоставили доступ, которым вы можете пользоваться по своему усмотрению. То, что вы написали эту строку и дали доступ в основную программу, лежит на совести того, кто писал класс Derived. По умолчанию доступ protected как раз режет доступ вне класса к данным и методам базового класса. Если конечно не расшарить их зачем то руками.

Добавлено через 59 секунд
Просто Саша, я просто не совсем пойму чего вы хотите добиться в итоге. Я пока лишь указал на то, что не надо было писать эту строку.
0
С чаем беда...
Эксперт CЭксперт С++
10012 / 5358 / 1467
Регистрация: 18.10.2014
Сообщений: 12,922
13.06.2018, 22:26 7
Цитата Сообщение от Просто Саша Посмотреть сообщение
В одном учебнике прочел вот такую фразу: УРОВЕНЬ ДОСТУПА К ЧЛЕНАМ БАЗОВОГО КЛАССА МОЖЕТ БЫТЬ ИЗМЕНЕН В ПРОИЗВОДНОМ КЛАССЕ, НО ТОЛЬКО В СТОРОНУ УЖЕСТОЧЕНИЯ.

Немного поэксперементировал и оказалось, что это не совсем так.
Самому кажется странным, что если в базовом классе какая-то функция определена как protected, то в производном классе она может быть сделана public.
А вообще как на данный момент обстоят с этим дела?
Вы правы. Пи помощи using-declaration вы можете повышать уровень доступа к доступным членам базового класса.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class B
{
protected:
  void foo() {}
public:
  void bar() {}
};
 
class D : protected B
{
public:
   using B::foo; // protected -> public
   using B::bar; // protected -> public
};
 
int main()
{
  D d;
  d.foo();
  d.bar();
}
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:28  [ТС] 8
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Просто Саша, почему не ответ? Вашему классу предоставили доступ, которым вы можете пользоваться по своему усмотрению. То, что вы написали эту строку и дали доступ в основную программу, лежит на совести того, кто писал класс Derived. По умолчанию доступ protected как раз режет доступ вне класса к данным и методам базового класса. Если конечно не расшарить их зачем то руками.
Ну, конечно, так не делается на практике. Вопрос то не в этом. Вы слышать то своего собеседника можете?
То что писать такую строку где попало не надо, я и сам знаю.

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы правы. Пи помощи using-declaration вы можете повышать уровень доступа к доступным членам базового класса.
А что стандарт говорит на это и как тогда относиться к учебнику, который говорит, что уровень доступа в производном классе можно только ужесточить?
0
С чаем беда...
Эксперт CЭксперт С++
10012 / 5358 / 1467
Регистрация: 18.10.2014
Сообщений: 12,922
13.06.2018, 22:28 9
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Просто Саша, я просто не совсем пойму чего вы хотите добиться в итоге. Я пока лишь указал на то, что не надо было писать эту строку.
Не совсем понимаю, откуда вы знаете, что автору кода "надо", а что "не надо". Вопрос был о том, можно ли повысить уровень доступа. Ответ - можно.

А "надо" или "не надо" - это вопрос посторонний и к теме никакого отношения не имеющий.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:31  [ТС] 10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вопрос был о том, можно ли повысить уровень доступа. Ответ - можно.
Можно даже сделать public то, что по всем канонам должно быть private. Речь идет о private наследовании. Тогда некоторые члены базового класса можно оставить public.
Это кстати говорит о том, на уровень доступа в производном классе спецификатор доступа в базовом классе оказывает большее влияние чем спецификатор наследование.
0
С чаем беда...
Эксперт CЭксперт С++
10012 / 5358 / 1467
Регистрация: 18.10.2014
Сообщений: 12,922
13.06.2018, 22:31 11
Цитата Сообщение от Просто Саша Посмотреть сообщение
А что стандарт говорит на это
Ничего нестандартного в этом нет.

Цитата Сообщение от Просто Саша Посмотреть сообщение
и как тогда относиться к учебнику, который говорит, что уровень доступа в производном классе можно только ужесточить?
Возможно, учебник просто хотел таким способом описать поведение ключевых слов public, protected, private в контексте наследования. Именно и только их. Они действительно могут только понижать.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 22:32 12
TheCalligrapher, я лишь пытался объяснить как работает "логика ужесточения", о которой говорил ТС в первом посту. Можно конечно это обойти с помощью using или указателей, но "это уже другая история". Если не использовать обходных маневров, то все будет работать как по учебнику, о котором писал автор.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:42  [ТС] 13
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Возможно, учебник просто хотел таким способом описать поведение ключевых слов public, protected, private в контексте наследования.
Так мне тоже хочется узнать, как правильно наследовать с изменением уровня доступа. ИМЕННО НАСЛЕДОВАТЬ, А НЕ ПЕРЕОПРЕДЕЛЯТЬ.

Добавлено через 4 минуты
Кстати насчет уровня private. Ведь этот один private другому private рознь.
Одно дело, когда мы в производном классе определим член с уровнем private и совсем другое дело, когда мы унаследуем private член из базового класса. В производном классе он просто недоступен. ПРЯМО ВПОРУ ГОВОРИТЬ ЕЩЕ ОБ ОДНОМ ЧЕТВЕРТОМ УРОВНЕ ДОСТУПА, ну назовем его скромно denied. А все они в то же время идут под одним уровнем доступа private.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 22:43 14
Цитата Сообщение от Просто Саша Посмотреть сообщение
Так мне тоже хочется узнать, как правильно наследовать с изменением уровня доступа. ИМЕННО НАСЛЕДОВАТЬ, А НЕ ПЕРЕОПРЕДЕЛЯТЬ.
Чтобы не "переопределять" не используйте using
Что касается наследования вы все правильно писали в вашем примере...
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 22:48  [ТС] 15
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Чтобы не "переопределять" не используйте using
Есть тут одна маленька загвоздка.
Стоит мне дополнить свой производный класс вот таким образом:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Derived : private Base
{
public:
    using Base::print;
    Derived(int x, int y) : Base {x}, d {y}
    {
    }
    auto print() -> void
    {
        Base::print();
        cout << "Derived class value: " << d << endl;
    }
private:
    
    int d;
};
И к тому, что было определено в директиве using уже не достучаться.
То есть я хочу одновременно унаследовать из базового класса функцию, но с другим уровнем доступа и одновременно переопределить ее в производном классе функцией с точно такой же сигнатурой.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 22:58 16
Просто Саша, все верно, вы же private-наследование использовали.

Вот тут можете табличку глянуть цветную.
https://cppforeach.wordpress.c... modifiers/

Добавлено через 7 минут
Цитата Сообщение от Просто Саша Посмотреть сообщение
То есть я хочу одновременно унаследовать из базового класса функцию, но с другим уровнем доступа и одновременно переопределить ее в производном классе функцией с точно такой же сигнатурой.
Так, давайте по порядку. Вот у меня такая программа.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
class Base
{
public:
    Base(int x) : b{ x }
    {
    }
    auto func(int x) -> void
    {
        b += x;
    }
protected:
    auto print() -> void
    {
        cout << "Base class value: " << b << endl;
    }
private:
    int b;
};
 
class Derived : private Base
{
public:
    using Base::print;
    Derived(int x, int y) : Base{ x }, d{ y }
    {
    }
    auto print() -> void
    {
        Base::print();
        cout << "Derived class value: " << d << endl;
    }
private:
 
    int d;
};
 
int main()
{
    Derived a(1, 2);
    a.print();
 
    system("pause");
    return 0;
}
Выдает такой результат:

Base class value: 1
Derived class value: 2

Что именно не устраивает в ее работе? Какой результат ее выполнения вы хотите видеть?
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 23:06  [ТС] 17
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Что именно не устраивает в ее работе? Какой результат ее выполнения вы хотите видеть?
Хочу вызвать метод, который унаследован при помощи директивы using.
То есть получить одну единственную строчку строчку: Base class value: 1
Но при этом использовать дескриптор производного класса.

Иными словами, есть
C++
1
using Base::print;
это один результат.
А есть и
C++
1
2
3
4
5
 auto print() -> void
    {
        Base::print();
        cout << "Derived class value: " << d << endl;
    }
Это другой результат.
Хочу иметь возможность через дескриптор производного класса одновременно пользоваться этими двумя функциям и.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 23:14 18
Цитата Сообщение от Просто Саша Посмотреть сообщение
Хочу вызвать метод, который унаследован при помощи директивы using.
Метод вы унаследовали и без директивы using, если что. Удалите в моем коде 28ю и 35ю строку. Как на счет такого варианта? Я все равно не пойму, зачем вам понадобился тут using. То что вы хотите, можно добиться и без него.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
13.06.2018, 23:23  [ТС] 19
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Метод вы унаследовали и без директивы using
Конечно, но не с тем уровнем доступа, который бы мне хотелось иметь.
0
1463 / 1005 / 455
Регистрация: 30.10.2017
Сообщений: 2,793
13.06.2018, 23:32 20
Просто Саша, хорошо, повысили вы уровень доступа через using. Какие дальше действия?

Добавлено через 5 минут
Просто Саша, напомню, сейчас у нас две функции в нашем примере. Base:: print, которая выдает строку

Base class value: 1


И функция Derived:: print, которая выдает строки

Base class value: 1 (через Base:: print)
Derived class value: 2
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.06.2018, 23:32
Помогаю со студенческими работами здесь

Организация наследования классов. Уровни доступа
Дана матрица размера M × N и целое число K (1 ≤ K ≤ N). После столбца матрицы с номером K вставить...

Создать абстрактный класс с общими полями и методами. В производных классах перегрузить чисто виртуальную функцию - общая стоимость всех изделий
Помогите пожалуйста!!! Не могу правильно создать абстрактный класс! Создать абстрактный класс с...

Почему нет доступа к данным-членам классов-родителей в классах-наследниках?
#include&lt;string&gt; using namespace std; class base { int i; public: base(int x) { i = x; }...

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru