1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.

С++ модификаторы доступа

Тема в разделе "Программирование", создана пользователем gerodoth, 12.10.16.

  1. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    Суть такова:
    на работе стали читать халявный курс по си++, препод из мфти, полезно, а я си как раз никогда не трогал, обходился, и решил что было бы полезно. Курс читается удаленно и медленно, на 2 года рассчитан, так я качнул приложение на андроиде и сам начал учить в свободное время. и дошел до места которое не втыкаю, пытался гуглить, но как-то так и не понял.
    итак:

    Public — доступ открыт всем, кто видит определение данного класса.
    Private — доступ открыт самому классу (т.е. функциям-членам данного класса) и друзьям (friend) данного класса, как функциям, так и классам.
    Protected — доступ открыт классам, производным от данного.

    зачем оно нужно?
    кодер пишет программу, выходит он скрывает определение класса от самого себя? или от других данных, но чтобы не давать модифицировать данные программисту достаточно не описывать способ их модификации в коде, разве не так?
    расскажите на пальцах.
     
  2. pmb

    pmb Активный участник

    4.798
    962
    gerodoth, вечная классика, когда-о за месяц по вечерам читалась на ура.

    ---------- Сообщение добавлено 12.10.2016 14:49 ----------

    gerodoth, посмотри что такое инкапсуляция в ООП
     
  3. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    вроде смотрел, не понял, но может оно.
    курс, зараза, на буржуйском, незнакомые слова пропускаю.
     
  4. Дмитрий Н

    Дмитрий Н Активный участник

    2.120
    396
    Модификаторы доступа - это реализация инкапсуляции. Если, например, речь вести не в контексте одного разраба и программки из трёх с половиной классов, а в контексте команды разработчиков, работающей над большим проектом или библиотекой, причём сама разработка сильно растянута во времени и в команде есть текучка, то модификаторы доступа позволяют скрывать часть реализации бизнес логики класса от внешнего мира, тем самым недавая в будущем плохо разобравшемуся в коде новичку выстрелить себе в ногу.
     
  5. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    я думал про такой вариант, но он вообще не на поверхности. это самый простой вариант?
    опять же зачем скрывать, не знаю как где, но в той же 1с конфига с нуля с задействованием кучи народа продвигается без этой заморочки, достаточно не нанимать "программистов", стреляющих по своим. наверняка и не только в 1с, просто это мне знакомо. выглядит как фича, притянутая за уши.
     
  6. Прохожий

    Прохожий Активный участник

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

    Это как в машине - ты заводишь автор поворотом ключа и никто не даёт тебе возможности отдельно включить бензонасос, активировать зажигание и подать напряжение на стартер на короткое время. А если бы давали, то 70% юзеров забывали бы выключать стартер. Поэтому его вызов и сделали приватным.
     
  7. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    примерно понятно, спасибо.

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

    Вложения:

  8. Леханссон

    Леханссон Активный участник

    843
    14
    На самом деле все константы типа "abcdef" храняться в специальной области памяти, которая инициалируется в момент запуска программы.
    Этим оператором мы всего лишь присваем указателю адрес этой области памяти.
     
  9. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    примерно так я и понял, чего ж они это не написали, примеров не привели, а задачки выдают.
     
  10. Прохожий

    Прохожий Активный участник

    5.602
    417
    а что делает оператор ++a в случае строки? Если бы символ - понятно
     
  11. Capitan Alex

    Capitan Alex Активный участник

    7.472
    77
    А что конкретно не понятно в первом примере ?
     
  12. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    ну как, рассказывали про типы, про то что переменной одного типа данные другого типа присвоить нельзя, а тут в задачках бац - символьному указателю и строку. задачки там рандомно генерятся, я думал пропустил что - перепроверил, не пропустил. почему символьному? почему он на начало строки указывает? как-то это все мутно без объяснения.
     
  13. Redrik

    Redrik Активный участник

    13.986
    5
    gerodoth, указатель " * " (звездочка) это, на самом деле число. Чаще всего ЛонгИнт (тоесть чаще всего это 64-биное число, но могут быть и варианты)
    Короче, указатель это число. Это адрес нулевой ячейки памяти в которой располагается какой-нть текст (char).
    А char - это тип указателя. Показывающий, что все, что идет начиная с адреса указателя - является чаром.
    В этом смысле этот Ваш char *a; ++a; указывает на второй и далее байт строки "12345"
    Т.е. cout << ++а; даст на выходе "2345"
    Есть отличие между а++, и ++а.
    В случае ++а - инкремент выполняется ДО начала вычислений всей строки (прединкремент)
    А а++ - после - постинкремент


    разберем Ваш первый пример

    char * a = "12345"; // *а = "12345"
    char * b = ++а; // в результате *а = "2345", *b = "2345" т.е. сначала инкрементируется переменная а, затем она присваивается указателю b. ВНИМАНИЕ! *а = "2345" и *b = "2345" это физически одни и те же данные. Если сделать а[3] = "8", то b станет равным "2348"
    cout << * ++b; //выдаст на стандартный поток вывода (чаще всего это консоль) - "345", т.к. в операции стоит прединкремент.

    ВНИМАНИЕ !
    В разных вариантах реализации библиотеки cout синтаксиса с++ (да и просто с) конструкция cout << * ++b; будет работать по разному.
    В некоторых вариантах cout << * ++b; выдаст саму строку b, в других выдаст число. Численное значение указателя b. А для вывода собственно строки b нужно написать cout << ++b;
    Смотря какой библиотекой пользоваться.

    И это тема очередной головной боли программистов.


    Второй вариант выдаст "hello"
    Третий строку "Learn"
     
  14. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    вот, и причем тут тогда char?

    не верно, по полю для ответа видно что поместится 1-2 символа, ну а судя по тому что указатель на символ то один.
    строку ни один вариант не выдает, везде символ. у задачек есть косяк - по длине поля ввода ответа можно прикинуть ответ.
     
  15. Redrik

    Redrik Активный участник

    13.986
    5
    Показывает компилятору и библиотекам, как с этой переменной общаться.

    например
    char * а;
    long int * b;

    операции а++ и b++ будут немного разными. В первом случае а будет увеличено на один байт (тоесть плюс один). А вот во втором, скорее всего на четыре байта.

    Ну и тот же cout.
    Как выводить *d если неизвестен тип этой переменной. Это чар, инт, лонг инт или вообще ссылка на объект.

    ---------- Сообщение добавлено 13.10.2016 15:40 ----------

    ????
     
  16. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    в ответе не строка а символ
     
  17. Redrik

    Redrik Активный участник

    13.986
    5
    gerodoth, прикольно,
    Символ это а[1] или b[3]
     
  18. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    вот и я так думал, но задачки повторяются иногда, стал тыкать символы, до этого индексы пробовал - нащупал,
    char * a = "12345"; // *а = '1'
     
  19. Redrik

    Redrik Активный участник

    13.986
    5
    Возможно.
    Не берусь спорить
    В бормане вроде *а - строка. В MS, вроде тоже.

    Но разные библиотеки по разному работают с указателями.
    И в большинстве это строка, а а[n] = это символ

    Но,если мне не изменяет память вроде в Qt, я встречал, например, что a это строка.
     
  20. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    ну тут уже объяснять не мне, может быть то что указатель символьного типа разрешает вывести только один символ, хз. по моей логике и я от нее пока не отвык указатель должен был быть типа строка, и возвращать строку, вот это было бы понятно.
     
  21. Redrik

    Redrik Активный участник

    13.986
    5
    А сейчас мало кто работает с чарами. Там столько заморочек с выделением памяти. Потом ее уничтожением. Плюс нельзя зайти за границу переменной, чтоб программа и не вылетела по эксепшену.
    Гораздо удобнее работать со String-ами

    Все эти задачки имеют лишь академический интерес.
    Ну и прививают дисциплину программирования. Как бы дается понимание внутренней структуры памяти компьютера и распределения в ней переменных.
     
  22. gerodoth

    gerodoth Активный участник

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

    Redrik Активный участник

    13.986
    5
    gerodoth, онлайновые компиляторы должны где-то быть.
    Поройся в инете.

    Накатай туда своих примеров и радуйся.
     
  24. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    да постфактум то можно, но по некоторым местам я не понял и после того как пощупал
     
  25. Redrik

    Redrik Активный участник

    13.986
    5
    ???
     
  26. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    ну вот про чар
     
  27. Redrik

    Redrik Активный участник

    13.986
    5
    Дык.

    Самый простой тип данных.
    Массив восьмибитовых байт.
     
  28. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    сегодня попалась со строковым указателем, так вот
    если string * k = "hello"
    что выдаст cout << (k += 2)?
     
  29. Redrik

    Redrik Активный участник

    13.986
    5
    gerodoth, стремная задачка.
    string * k это указатель на массив string-ов он как бы не может быть равен char*
    Там или конструктор вида string k = "hello" //без звездочки
    Или string * k = {"hello", "the", "world"}; // за синтаксис могу ошибаться, но вроде бы элементы массива в фигурных скобках
    Однако в С++ вместо string * k более привычна запись string k[ ]

    Для первого случая оператор += должен быть перегружен внутри класса и, скорее всего, cout << (k += 2) выдаст "hello2" //тоже от реализации класса зависит
    А для второго случая - "world" или даже ошибку
     
  30. gerodoth

    gerodoth Активный участник

    10.423
    1.256
    можт условия с ошибкой запомнил, но в ответе "llo"
    еще раз попадется поправлю