Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переопределение уровня доступа для метода произ-, водного класса 
V
    Опции темы
zim22
Дата 30.4.2009, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



В классе Set я указываю, что функция head является закрытой.
Тем не менее функция listehead получает к ней доступ... 
Я считаю, что это неправильно, т.к. нарушается инкапсуляция класса Set.
Ведь мы не имеем права вызывать в клиентском коде private функции...
Вопрос: где я протупил? smile
Код

class List {
public:
  virtual void *head() { return 0; }  
};

class Set : public List {
private:
  using List::head;
};

void *listhead(List &l) {
  return l.head();
}


Код

int main() 
{
  Set s;
  void *p = listhead(s);  
}



--------------------
PM MAIL   Вверх
azesmcar
Дата 30.4.2009, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



А вот так? smile 
Код

void *listhead(Set &l) {
    return l.head();
}

PM   Вверх
zim22
Дата 30.4.2009, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  30.4.2009,  09:48 Найти цитируемый пост)
А вот так?

я хотел полиморфное поведение. Для этого и передаю в функцию listhead ссылку на базовый класс.

Хорошо, изменим класс Set так, чтобы явно переопределить вирт.функцию.
И она всё-равно вызывается...
Код

class Set : public List {
private:  
  virtual void *head() { return (void*)0xffffffff; }
};


Это сообщение отредактировал(а) zim22 - 30.4.2009, 09:53


--------------------
PM MAIL   Вверх
azesmcar
Дата 30.4.2009, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22, 
Но вызываете то вы функцию по указателю базового класса, а в базовом классе функция открыта. 

PM   Вверх
Fazil6
Дата 30.4.2009, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(zim22 @  30.4.2009,  09:51 Найти цитируемый пост)
я хотел полиморфное поведение. Для этого и передаю в функцию listhead ссылку на базовый класс. 

ну так в базовом классе она ведь public.
PM MAIL   Вверх
zim22
Дата 30.4.2009, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  30.4.2009,  09:55 Найти цитируемый пост)
Но вызываете то вы функцию по указателю базового класса, а в базовом классе функция открыта. 

В базовом - она открыта, да. Но вызывается в конечном счёте функция не базового класса, а производного. А в производном классе функция находится в разделе private...
Т.е. я правильно понимаю: с какой меткой доступа функция была объявлена в базовом классе - с такой меткой она и будет вызываться в производных, независимо от того, в каком разделе(public, private) производного класса она находится?

Это сообщение отредактировал(а) zim22 - 30.4.2009, 10:00


--------------------
PM MAIL   Вверх
azesmcar
Дата 30.4.2009, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

Ну для начала стоит понять одну вещь
Проверка идет компайл тайм, какая функция на самом деле будет вызвана - компайл тайм неизвестно так как функция виртуальная. И второе, такое поведение вполне нормально и с точки зрения С++ и с точки зрения логики.
PM   Вверх
zim22
Дата 30.4.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  30.4.2009,  10:01 Найти цитируемый пост)
Проверка идет компайл тайм, какая функция на самом деле будет вызвана - компайл тайм неизвестно так как функция виртуальная.

c этим согласен. всё логично.

Цитата(azesmcar @  30.4.2009,  10:01 Найти цитируемый пост)
 И второе, такое поведение вполне нормально...с точки зрения логики.

с точки зрения моей логики это не нормально: какое право имеет сторонняя функция, не объявленная как firend, вызывать private функции класса...



--------------------
PM MAIL   Вверх
Fazil6
Дата 30.4.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(zim22 @  30.4.2009,  09:58 Найти цитируемый пост)
Т.е. я правильно понимаю: с какой меткой доступа функция была объявлена в базовом классе - с такой меткой она и будет вызываться в производных, независимо от того, в каком разделе(public, private) производного класса она находится?

нет конечно, неправильно ты понимаешь...
права доступа определяются по типу переменной. У тебя тип List. Вот по его объявлению и определяется что для переменной l  открыто , а что нет. Если тип будет Set, то тогда по нему и будет определяться
PM MAIL   Вверх
azesmcar
Дата 30.4.2009, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

Цитата

с точки зрения моей логики это не нормально: какое право имеет сторонняя функция, не объявленная как firend, вызывать private функции класса...


Код

class A
{
private:
   void foo() { /* ... */ };
public:
   void call_foo() {
      foo();
   }
}

int main()
{
   A t;
   t.call_foo();
}

вот тут тоже вызывается. Это нелогично?


Это сообщение отредактировал(а) azesmcar - 30.4.2009, 10:08
PM   Вверх
mes
Дата 30.4.2009, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(zim22 @  30.4.2009,  08:58 Найти цитируемый пост)

В базовом - она открыта, да. 

Интерфейс же базового класса  не изменился от того, что Вы определили производный. 
Цитата(zim22 @  30.4.2009,  08:58 Найти цитируемый пост)

 Но вызывается в конечном счёте функция не базового класса, а производного. А в производном классе функция находится в разделе private... Не понимаю... 

1. Для функции List::head в классе Set Вы переопределили лишь ее реализацию 
2. Для класса Set определили такой интерфейс в котором функция Set::head () приватна.
Первое со вторым никак не связано и не пересекается. smile



Это сообщение отредактировал(а) mes - 30.4.2009, 10:09


--------------------
PM MAIL WWW   Вверх
Fazil6
Дата 30.4.2009, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(zim22 @  30.4.2009,  10:05 Найти цитируемый пост)
с точки зрения моей логики это не нормально: какое право имеет сторонняя функция, не объявленная как firend, вызывать private функции класса...

странная у тебя логика. Ты сказал, что у тебя 
Код

void *listhead(List &l) {
  return l.head();
}

Где ты тут видишь вызов private функции класса? l - это ссылка на List вне зависимости что ты туда на самом деле передал.  
Как компилятор должен по твоему понять закрыта или нет функция?
PM MAIL   Вверх
zim22
Дата 30.4.2009, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  30.4.2009,  10:07 Найти цитируемый пост)
вот тут тоже вызывается. Это нелогично?

логично. т.к. внутри класса мы имеем доступ к private функциям. 
в моём примере функция listhead объявлена вне класса. и никаких прав на доступ к private переменным/функциям класса она не имеет.

Цитата(Fazil6 @  30.4.2009,  10:09 Найти цитируемый пост)
Как компилятор должен по твоему понять закрыта или нет функция?

заглянуть в интерфейс класса List и посмотреть метку доступа функции head. она там public. значит всё ОК, можно компилить.

Это сообщение отредактировал(а) zim22 - 30.4.2009, 10:16


--------------------
PM MAIL   Вверх
mes
Дата 30.4.2009, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(zim22 @  30.4.2009,  09:10 Найти цитируемый пост)
в моём примере функция listhead объявлена вне класса. и никаких прав на доступ к private переменным/функциям класса она не имеет.

В твоем примере она ничего не знaет о правилах Set.



--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 30.4.2009, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

user posted image

Добавлено @ 10:19
Переведу на всякий случай smile
Доступ проверяется в момент вызова, используя тип который был использован для вызова. Доступ для функции-члена в классе в котором вызываемая функция была определена - в общем случае неизвестна.


Это сообщение отредактировал(а) azesmcar - 30.4.2009, 10:29
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0582 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.