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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.70
dimcoder
Полярный
458 / 431 / 67
Регистрация: 11.09.2011
Сообщений: 1,129
#1

Доступ к закрытым элементам класса - Вопрос - C++

18.11.2011, 10:00. Просмотров 3193. Ответов 17
Метки нет (Все метки)

Доброго всем времени суток. Итак, столкнулся с одной непонятной вещью, связанной с классами, а точнее с private элементами. Вот код:

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
#include <iostream.h>
#include <conio.h>
 
class array
{
   public:
 
   array(int = 10);
 
   int getsize(array&);
 
   private:
 
   int size;
};
 
array::array (int y)
{
   size = y;
}
 
array::getsize(array &a)
{
   return a.size;   //По идее компилер должен выдавать ошибку так как я пытаюсь получить доступ к закрытому элементу !
}
 
main ()
{
   array a, b(200);
 
   cout << a.getsize(b) << endl;
 
   getch();
 
   clrscr();
 
   return 0;
}
Выводит 200.

Почему компилятор не выдаёт ошибку? Инкапулсуляция ф большой и тёмной ж? Ну а если серьёзно, то у меня пока выресовывается одно объяснение: объекты одного и того же класса имеют доступ к закрытым элементам того же класса по средствам функций элементам. Объясните пожалуйста чайнику что к чему.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2011, 10:00
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Доступ к закрытым элементам класса - Вопрос (C++):

Доступ к закрытым членам класса(шаблона) - C++
Вопрос почему компилятор выдает ошибку в функции main? Ситуация следующая имеется шаблон (класс) элемента списка, реализован шаблон (класс)...

Доступ к закрытым членам базового класса - C++
помогите понять что я не так сделал ? #include &lt;iostream&gt; using namespace std; class A { int PrA1; public: int...

Дружественная функция-оператор, доступ к закрытым полям класса - C++
У меня есть класс MyClass, вот код: class MyClass { int x, y; public: MyClass(); friend ostream &amp; operator &lt;&lt; (ostream &amp;,...

Может ли объемлющий класс иметь неограниченный доступ к элементам вложенного класса? А вложенный класс — к элементам объемлющего? - C++
Ответ как бы знаю(нет , да). но наверное я что-то не так понимаю, т.к. примерчик написать не получается. class BaseClass { ...

Классы С++, получить доступ из одного класса к элементам другого - C++
Здравствуйте! Объясните пожалуйста, вот имеется у меня два класса,например вот такие: Class A { private: int i; }

Доступ к закрытым конструкторам и деструкторам - C++
Как осуществить доступ к закрытым конструктором и деструкторам и конструкторам через методы класса?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Bers
Заблокирован
18.11.2011, 10:11 #2
Цитата Сообщение от dimcoder Посмотреть сообщение
Ну а если серьёзно, то у меня пока выресовывается одно объяснение: объекты одного и того же класса имеют доступ к закрытым элементам того же класса по средствам функций элементам.
верно


Цитата Сообщение от dimcoder Посмотреть сообщение
Инкапулсуляция ф большой и тёмной ж?
не верно
dimcoder
Полярный
458 / 431 / 67
Регистрация: 11.09.2011
Сообщений: 1,129
18.11.2011, 10:20  [ТС] #3
Bers, спасибо. Интерессно получается...

Не по теме:

Инкапсуляция так заинкапсулирована, что никакая инкапсуляция не разинкапсулирует заинкапсулированную инкапсуляцию. Сам щас тока придумал. Бред дня короче.

Bers
Заблокирован
18.11.2011, 10:25 #4
Вы просто не совсем понимаете, что такое "инкапсуляция".
Инкапсуляция - это сокрытие внутренностей объекта от всего внешнего мира.

Представьте себе, что объект - это периметр. Этакий забор. Внутри этого забора спрятаны все кишки. Снаружи не видно, что там внутри.

У этого периметра есть ворота (паблик-методы). Только через эти ворота можно что то отправить вовнутрь, или получить наружу.


Инкапсуляция касается только внешнего мира. Но если оказаться по другую сторону забора - внутри периметра, то вы увидите и все данные, и весь механизм внутренной реализации объекта.

Кто находится по ту сторону (внутри) забора? Сам объект и находится. Только сам объект знает свои данные, и как он устроен. И если объекты одного и того же класса, значит они знают об устройстве друг друга. Поэтому, инкапсуляция не распространяется на объекты одного класса.
Они "знают" точное устройство друг друга. Знают свою собственную природу. Знает её и тот разработчик, который эти классы создавал.

Не знают только внешний мир - пользователи. И их пользовательские коды.

Но сами объекты одного класса имеют одинаковую природу, и знают как они устроена.
Поэтому, они могут "видеть" устройство (приватные данные и методы) друг друга.
На самом деле они не "видят", они просто "знают" её.

Для всех остальных - только через ворота.

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

Добавлено через 2 минуты
блин... бессонная ночь сказывается. Сам прочел ток что написал - тавтология сплошная.

Но смысл вы вроде бы должны уловить...
outoftime
║XLR8║
509 / 431 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
18.11.2011, 10:31 #5
Цитата Сообщение от Bers Посмотреть сообщение
Вы просто не совсем понимаете, что такое "инкапсуляция".
Инкапсуляция - это сокрытие внутренностей объекта от всего внешнего мира.
100% правильно, внутри объекта видимы все поля этого объекта + public & protected от парента, иначе и быть не может, как создать объект и пользоваться им если все поля закрыты в нем же самом??? 0_о ТС жжет...
dimcoder
Полярный
458 / 431 / 67
Регистрация: 11.09.2011
Сообщений: 1,129
18.11.2011, 10:34  [ТС] #6
Цитата Сообщение от Bers Посмотреть сообщение
Даже в этом случае если есть возможность - лучше использовать хотя бы приватные, но методы. А если нет такой возможности - ничто не мешает создать метод в приватной зоне
Не совсем понятно, что Вы имеете ввиду. Приватные методы - это что не одно и то же что и методы в приватной зоне?
ЗЫ Можно ли оградить каждый объект класса такими же заборами? НУ чтоб не видели и всё тут. Догадываюсь что нет.
Bers
Заблокирован
18.11.2011, 10:49 #7
Цитата Сообщение от dimcoder Посмотреть сообщение
Ы Можно ли оградить каждый объект класса такими же заборами? Догадываюсь что нет.
Можно ли оградить объект от знания об устройстве других объектов своего же класса?
Можно. Только это - идиотизмом попахивает.

Добавлено через 2 минуты
Цитата Сообщение от dimcoder Посмотреть сообщение
Приватные методы - это что не одно и то же что и методы в приватной зоне.
Это одно и тоже.

Но вообще, я подумал, что у вас какие то свои понятия просто имеются. Что бы убедится, что мы понимаем друг друга правильно, давайте уточним:

Что такое по вашему "приватный метод" ?
Что такое по вашему "метод, который находится в приватной зоне" ?

В чем между ними принципиальное различие?

Добавлено через 6 минут
Ниже представлен код с пояснением в комментариях.

Во втором случае класс "отказывается" выполнять приведение типов.
Технически он "может" и даже "умеет". Но на деле - отказывается это сделать.

Тот, кто поймёт почему - тот поймёт, что такое инкапсуляция.

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
struct sData { int a,b; };
 
struct CTest:public sData 
{ 
    CTest():sData(){} 
};
 
struct CTest1:protected sData 
{ 
    CTest1():sData(){} 
};
 
int main()
{
    CTest test;
    CTest1 test2;
 
    //1 Случай.
    //приведение в стиле си
    sData temp = (sData) test;  //работает
    
    //приведение в стиле с++
    sData temp1 =  static_cast<sData>(test); //работает
 
 
    //2 Случай.
    //приведение в стиле си
    sData temp3 = (sData) test2; //ошибка компиляции
    
    //приведение в стиле с++
    sData temp4 =  static_cast<sData>(test2); ////ошибка компиляции
 
    //error C2243: приведение типов: 
    //преобразование "CTest1 *" в "const sData &" существует, но недоступно
    
   return 0;
}
dimcoder
Полярный
458 / 431 / 67
Регистрация: 11.09.2011
Сообщений: 1,129
18.11.2011, 10:49  [ТС] #8
Вот именно что в моём понятии - нету разницы. На слух воспринимается как одно и то же.
C++
1
2
private:
   void func_utility(void);
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
18.11.2011, 10:54 #9
Цитата Сообщение от Bers Посмотреть сообщение
преобразование "CTest1 *" в "const sData &" существует, но недоступно
Не бывает такого преобразования
Bers
Заблокирован
18.11.2011, 11:01 #10
Цитата Сообщение от dimcoder Посмотреть сообщение
Не совсем понятно, что Вы имеете ввиду.
Кажется, я понял суть вопроса.

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

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


Бывают ситуации, когда приходится разрабатывать класс в таких условиях, когда ещё точно не знаешь даже, какой у него будит конечный интерфейс. В этом случае, чем меньше точек доступа к данным класса, тем меньше в случае чего придётся править уже существующего кода.

И тем выше вероятность, что легко можно будит отнаследоваться от такого класса, что бы породить новый класс более точно отвечающий новым условиям задачи.


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

Добавлено через 19 секунд
Цитата Сообщение от Deviaphan Посмотреть сообщение
Не бывает такого преобразования
Первый случай наглядно показывает, что бывает

Во втором случае класс пытается "защититься" от внешней агрессии.

Он говорит: по закону инкапсуляции, я не имею права выдавать вам своих стариков (базовые классы).
Пользователь может быть в недоумении.

Но разработчик класса то знает, что старики потомка находятся под его защитой.

И наверное, у разработчика были свои особые причины сделать так, что бы базовые классы были "понадежнее" упрятаны.
Например, что бы максимально затруднить хак класса, на предмет прямого доступа к его данным членам снаружи.
Что бы уж точно получить доступ к приватным данным-членам класса снаружи "ничайно" не получился.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
18.11.2011, 11:08 #11
Цитата Сообщение от Bers Посмотреть сообщение
Первый случай наглядно показывает, что бывает
Нельзя указатель преобразовать в ссылку. Ни в каком случае. Верно и обратное.
Bers
Заблокирован
18.11.2011, 11:10 #12
Цитата Сообщение от Deviaphan Посмотреть сообщение
Нельзя указатель преобразовать в ссылку. Ни в каком случае. Верно и обратное.
Я вам ещё раз говорю, в первом случае все прекрасно приводится, и кастуется.
Не верите - скомпилируйте.

"указатель-ссылка" существуют только "внутри" компилятора когда он преобразовывает типы от потомка к базовому.
преобразовать тип от потомка к базовому можно.

Так что вы чего то там ни о том подумали.
В 10# посту даже подсказку решил оставить для новичков.
А сообщение компилятора не нужно принимать слишком буквально. Там приводится тип потомка к типу его базового класса. "Ссылки-указатели " - внутренний продукт самой студии.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
18.11.2011, 11:28 #13
Цитата Сообщение от Bers Посмотреть сообщение
Я вам ещё раз говорю, в первом случае все прекрасно приводится, и кастуется.
При чём тут классы вообще?
C++
1
2
3
int a = 10;
int & b = a;
int * c = b; // Fail

Цитата Сообщение от Bers Посмотреть сообщение
преобразовать тип от потомка к базовому можно.
С этим и не спорю.

Цитата Сообщение от Bers Посмотреть сообщение
в первом случае все прекрасно приводится, и кастуется.
Там нет приведения ссылок к указателю. Ни внутри, ни снаружи.
А вот срезка есть, да.
Bers
Заблокирован
18.11.2011, 11:30 #14
Цитата Сообщение от Deviaphan Посмотреть сообщение
При чём тут классы вообще?
А при чем тут ссылки-указатели?
Где вы там в первом, или во втором случае увидели ссылки-указатели?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
18.11.2011, 11:31 #15
Цитата Сообщение от Bers Посмотреть сообщение
//error C2243: приведение типов: //преобразование "CTest1 *" в "const sData &" существует, но недоступно
Вот там.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2011, 11:31
Привет! Вот еще темы с ответами:

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

Friend функции не имеют доступ к закрытым переменным - C++
Всем привет. Изучаю c++ по Липпману 5-ое издание. Там на стр. 351-352 используются friend функции для получения доступа к закрытым...

Получение доступа к закрытым методом класса - C++
Как получить доступ к закрытому конструктору и деструктору?

Реализовать функции доступа к закрытым полям класса - C++
Определен следующий класс : struct Cls { Cls(char c, double d, int i); private: char c; double d; int i; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
18.11.2011, 11:31
Ответ Создать тему
Опции темы

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