Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.58/40: Рейтинг темы: голосов - 40, средняя оценка - 4.58
13 / 13 / 11
Регистрация: 03.09.2011
Сообщений: 1,026

Вопрос про Спецификаторы доступа Public и Private

28.10.2011, 15:38. Показов 8417. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Читаю Дейтлов...
Дошел до объяснения спецификаторов и не могу понять 2 предложения:
Доступ по умолчанию к элементам класса-закрытый(private),поэтому все элементы между заголовком класса и первым спецификатором доступа являются закрытыми .Спецификаторы public и 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
class GradeBook
{
public:
  
   void setCourseName( string name )
   {      
      courseName = name; // store the course name in the object
   } 
   
 
   string getCourseName() 
   {
      return courseName;
   } 
 
 
   void displayMessage()
   {
    
      cout << "Welcome to the grade book for\n" << getCourseName() << "!" 
         << endl;
   } 
private:
   string courseName; 
};
А почему строка
C++
1
2
3
4
   } 
private:
   string courseName; 
};
объявлена в самом конце,а не в начале ?Ведь переменная должна объявляться до ее использования.
Еще комментарий к этой же строке написан "Название курса для данного GradeBook".Как это понимать?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.10.2011, 15:38
Ответы с готовыми решениями:

Модификаторы доступа public, private, protected
Есть ли в Си модификаторы доступа public, private, protected?

Изменить модификаторы доступа public к полям класса на private
Был тут вот такой код: namespace ConsoleApplication3 { class Room { public double length; //длина ...

Public и Private
Доброго времени суток! Написал код и понял, что некоторые методы должны быть private, а не public. Если переношу их в private, то...

42
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
28.10.2011, 20:30
Студворк — интернет-сервис помощи студентам
Сыроежка, а можно ещё пример?
0
Заблокирован
28.10.2011, 20:33
C++
1
2
3
4
5
[quote=Сыроежка;2114418]struct A
{
* *enum { size = 10 };
* *int a[size];
};[/quote]
Ни в каком порядке не компилируется. Если только енум за рамки класса вытащить.
с другой стороны, если класс уже знает все те типы, с которыми будут оперировать его данные-члены или методы, то объявлять последние можно в любом порядке. Ага.



аааа.. скомпилировалось. Да
0
Заблокирован
28.10.2011, 20:36
Цитата Сообщение от Bers Посмотреть сообщение
C++
1
 
Ни в каком порядке не компилируется. Если только енум за рамки класса вытащить.
с другой стороны, если класс уже знает все те типы, с которыми будут оперировать его данные-члены или методы, то объявлять последние можно в любом порядке. Ага.
Почему у вас не компилируется? Что за ошибка выскакивает? Может быть где-то опечатка?

Добавлено через 2 минуты
Цитата Сообщение от silent_1991 Посмотреть сообщение
Сыроежка, а можно ещё пример?
Если на эту тему, то пожалуйста.

C++
1
2
3
4
5
6
7
const int i = 10;
 
struct A
{
   int a[i];
   static const int i = 5;
};
C++
1
2
3
4
5
6
7
const int i = 10;
 
struct A
{
   static const int i = 5;
   int a[i];
};
Хотя этот класс , как говорится, ill-formed, но тем не менее компиляторы спокойно пропускают этот код, и результат будет разным в зависимости от следования членов класса.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
28.10.2011, 20:39
Сыроежка, а вот глобальные переменные сюда вмешивать не надо, задача зачастую меняется при введении дополнительных условий. Да и в самом начале я говорил несколько о другом, подразумевал скорее взаимодействие полей-данных с методами.
0
Заблокирован
28.10.2011, 20:40
Сыроежка, вы осознаете что объявляете новый тип данных на основе уже существующего типа данных?

Ну то есть, вы не используете в классе существующие типы данных, а создаете новые типы прям в объявлении класса. Ничего удивительного, что при таком подходе появляются левые зависимости между типами, а сам класс легко может пофейлится
0
Заблокирован
28.10.2011, 20:42
Цитата Сообщение от silent_1991 Посмотреть сообщение
Сыроежка, а вот глобальные переменные сюда вмешивать не надо, задача зачастую меняется при введении дополнительных условий. Да и в самом начале я говорил несколько о другом, подразумевал скорее взаимодействие полей-данных с методами.
Ни в начале, ни сейчас вы ничего правильного в соответствии со стандартом не говорите, а лишь фантазируете! Нужно корректно формулировать утверждения. Стандарт ясно говорит, когда неквалифицированное имя ищется в области имени класса. Я по памяти не помню, но это относится к определениям функций-членов класса, к определению их параметров, к определению аргументов по умолчанию, к ctor-инициализации конструктора, к определениям статических членов класса. Тем не менее порядок следования объявлений членов-данных класса внутри класса очень важен, если опредедение одного члена-данного зависит от определения другого члена-данного.!
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
28.10.2011, 20:44
Сыроежка, вы, конечно, всё сформулировали очень внятно, спасибо вам от всех нас за это.

Цитата Сообщение от Сыроежка Посмотреть сообщение
если опредедение одного члена-данного зависит от определения другого члена-данного.!
Ключевая фраза.
1
Заблокирован
28.10.2011, 20:45
Цитата Сообщение от Bers Посмотреть сообщение
Сыроежка, вы осознаете что объявляете новый тип данных на основе уже существующего типа данных?

Ну то есть, вы не используете в классе существующие типы данных, а создаете новые типы прям в объявлении класса. Ничего удивительного, что при таком подходе появляются левые зависимости между типами, а сам класс легко может пофейлится
Я не совсем понял вашу тирпаду, но я вам привел второй пример, где никакие новые типы не объявляются внутри класса. Можно привести более интересеные примеры, когда есть наследование классов. Так как новое имя члена будет скрывать имя члена базового класса. Поэтому порядок объявления членов производного класса будет важен, если они зависимы между собой.
0
Заблокирован
28.10.2011, 20:50
Цитата Сообщение от Сыроежка Посмотреть сообщение
int a[i];
обявление нового типа данных.
И этот новый тип данных - масив целых чисел зависит от i

возникает зависимость между массивом a и переменой i

при СОЗДАНИИ нового типа, компилятору нужно знать всю информацию о том, при помощи чего новый тип создаётся.

Если сделать так:

C++
1
2
3
4
5
6
 struct A
    {
        
        int a[i]; // error C2065: i: необъявленный идентификатор
        static const int i = 5;
    };
Что бы не иметь таких проблем, весь необходимый классу тулс должен быть приинклюден перед объявлением класса. Сам же класс только ОБЪЯВЛЯЕТ данные члены (а не создаёт)

Определение же методов никак не зависит от порядка объявления данных-членов

/зы вы ступали понятие "объявления" типа, с понятием "создание" типа
0
Заблокирован
28.10.2011, 20:54
Цитата Сообщение от Bers Посмотреть сообщение
обявление нового типа данных.
И этот новый тип данных - масив целых чисел зависит от i

возникает зависимость между массивом a и переменой i

при СОЗДАНИИ нового типа, компилятору нужно знать всю информацию о том, при помощи чего новый тип создаётся.

Если сделать так:

C++
1
2
3
4
5
6
 struct A
    {
        
        int a[i]; // error C2065: i: необъявленный идентификатор
        static const int i = 5;
    };
Что бы не иметь таких проблем, весь необходимый классу тулс должен быть приинклюден перед объявлением класса. Сам же класс только ОБЪЯВЛЯЕТ данные члены (а не создаёт)

Определение же методов никак не зависит от порядка объявления данных-членов

/зы вы ступали понятие "объявления" типа, с понятием "создание" типа
Увы, я не знаю, что такое "создание типа". Проблема на самом деле лежит в том, что вы не знаете станадарта, а фантазируете! Я уже написал, в каких случаях неквалифицированное имя ищется в области видимости класса. Вы же по-прежнему безграмотно пытаетесь что-то там нафантазировать!

Читайте внимательно то, что пишет Сыроежка, и будет вам счастье!
0
Заблокирован
28.10.2011, 21:01
Цитата Сообщение от Сыроежка Посмотреть сообщение
Увы, я не знаю, что такое "создание типа".

C++
1
2
3
4
5
 struct A  //создание нового типа
    {
       struct B{};  //создание нового типа
       B b;
    };
C++
1
2
3
4
5
6
7
 struct A  //создание нового типа
    {
       
       B b; //нельзя. что бы построить b компилятор УЖЕ должен знать что такое тип B
       struct B{};  //создание нового типа
       
    };

Создавать новые типы внутри создаваемых типов - практика ведущая к ошибкам.
0
28.10.2011, 21:02

Не по теме:

Чёрт, почему на форуме нет молящегося смайлика?.. :wall:

0
Заблокирован
28.10.2011, 21:06
Цитата Сообщение от Bers Посмотреть сообщение
C++
1
2
3
4
5
 struct A
    {
       struct B{};  //создание нового типа
       B b;
    };
C++
1
2
3
4
5
6
7
 struct A
    {
       
       B b; //нельзя. что бы построить b компилятор УЖЕ должен знать что такое тип B
       struct B{};  //создание нового типа
       
    };

Создавать новые типы внутри создаваемых типов - практика ведущая к ошибкам.
Вообще-то, в С++ есть такие понятия, как объявление и определение. Этими понятиями и надо пользоваться. В вашем примере внутри struct A определяется struct B. Определения классов вводят новые имена типов.

И почему вы сделали вывод про "практику, ведущую к ошибкам", я не знаю. Это, например, часто делается при объявлении стандартных контейнеров. Например, итераторы определяются внутри класса контейнера.

P.S. Добавлю также, чтобы вы знали, когда класс только объявляется без его определения. Это когда имя класса вводится с помощью уточненного спецификатора типа (elaborated type specifier). Например,

C++
1
2
3
struct A;  // это только объявление.
 
struct A { int a; };  // а это его определение
0
Заблокирован
28.10.2011, 21:14
Цитата Сообщение от Сыроежка Посмотреть сообщение
Вообще-то, в С++ есть такие понятия, как объявление и определение. Этими понятиями и надо пользоваться.
При объявлении класса, мы объявляем данные-члены класса. То есть, мы говорим компилятору: у этого класса будут вот такие данные-члены.


Какие такие? Если к моменту объявления данных-членов, их тип неизвестен компилятору, то это ошибка. Это попытка определить ещё не объявленный тип данных .

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


Создание нового типа - объявление типа (не данных-членов этого типа, а самого типа). Понятие очень удобное, дабы не путаться между "объявлением" и "определением" в зависимости от контекста.
0
Заблокирован
28.10.2011, 21:16
Цитата Сообщение от Bers Посмотреть сообщение
При объявлении класса, мы объявляем данные-члены класса. То есть, мы говорим компилятору: у этого класса будут вот такие данные-члены.


Какие такие? Если к моменту объявления данных-членов, их тип неизвестен компилятору, то это ошибка. Это попытка определить ещё не объявленный тип данных .

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


Создание нового типа - объявление типа (не данных-членов этого типа, а самого типа). Понятие очень удобное, дабы не путаться между "объявлением" и "определением" в зависимости от контекста.
Нет, лучше не пользоваться доморощенными терминами, так как они не унифицированы и могут только запутывать других людей, с кем вы общаетесь, так как они могут в это вкладывать свой смысл.

В стандарте четко говорится, что является объявлением, а что является при этом определением.

С чем я не согласен со стандартом, это то, что typedef не только является объявлением, как написано в стандарте, но может играть роль определения, если используется для классов или перечислений.
0
Заблокирован
28.10.2011, 21:22
Сыроежка, суть же довольно проста: вы не можете объявлять в классе данные-члены, типы данных которых классу ещё не известны.

Цитата Сообщение от Сыроежка Посмотреть сообщение
struct A { int a; }; *// а это его определение
Это определение самого класса. А вот сами типы данных-членов должны быть известны классу к моменту их объявления в классе.

Если я что-то путаю, попровьте меня.
0
Заблокирован
28.10.2011, 21:34
Цитата Сообщение от Bers Посмотреть сообщение
Сыроежка, суть же довольно проста: вы не можете объявлять в классе данные-члены, типы данных которых классу ещё не известны.



Это определение самого класса. А вот сами типы данных-членов должны быть известны классу к моменту их объявления в классе.

Если я что-то путаю, попровьте меня.
Типы неизвестны не классу, а компилятору.. Компилятор осуществляет поиск используемых неквалифицированных имен согласно определенному алгоритму. То есть, например, некоторое имя может быть объявлено в пространстве имен, которое заключает в себе определение класса. Может также использоваться директива using. У меня есть на эту тему сообщение на www.clipper.borda.ru.
0
Заблокирован
28.10.2011, 21:35
уберите, пока не забанили)
0
Заблокирован
28.10.2011, 21:36
Цитата Сообщение от Bers Посмотреть сообщение
уберите, пока не забанили)
Пусть уберет тот, у кого руки чешутся.
0
Заблокирован
29.10.2011, 15:19

Не по теме:

Цитата Сообщение от Сыроежка Посмотреть сообщение
Пусть уберет тот, у кого руки чешутся.
ви таки есть анархист!
*деловито срисовал ссылочку*



Добавлено через 17 часов 42 минуты
кстати. Вот очень красноречивый пример того, насколько реально важен порядок объявления данных-членов класса:

1. От порядка, в котором объявляются данные члены класса зависит размер класса:

C++
1
2
3
4
5
    struct test { int i,n;  char c;       };
    struct test2 { int i; char c; int n;   };
 
    std::cout<< sizeof(test)<<std::endl;
    std::cout<< sizeof(test2)<<std::endl;
2. ВАЖНЫЙ МОМЕНТ!!!!
От порядка объявления данных членов в классе зависит то, насколько корректно сработает инициализация данных-членов в списке инициализации:



C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <class tName, class tCont = std::vector<tName> >
class CTest
{
public:
    CTest(cSize_a nSizeX, cSize_a nSizeY, const tName& nNullElement=tName() );
private:
    //если данные члены переставить местами
    //myTable проинициализируется мусором, 
    //а не корректным значением myNULL_Element
    tName myNULL_Element;   
    std::vector<tCont> myTable;
};
 
template <class tName, class tCont>
CTest<tName, tCont>::CTest(cSize_a nSizeX, cSize_a nSizeY, const tName& nNullElement=tName() ):
myNULL_Element(nNullElement),
myTable(nSizeY, tCont(nSizeX,myNULL_Element) )
{}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.10.2011, 15:19

Private и public
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type ...

Public: и private:
Вопрос: данные модиф. доступа могут быть записаны только 1 раз каждый class sample1{ public: int a; private: ..... }; или...

Public/private
Подскажите, пожауйста, где можно почитать про Public и Private механизмы создания документов? А то везде как-то вскольз упомянуто... Я...

Из private в public
Доброго времени суток. Подскажите, есть ли способ &quot;в ходе выполнения кода&quot; изменить статус переменной (свойства) из private в public (и/или...

Классы (private, public)
Всем добра, недавно начал осваивать С# (дня два). Нужна Ваша помощь, вернее совет, по поводу классов в C#. Создал программку...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Оказывается, Unreal Engine позволяет качество на порядки выше, чем было в Lineedge
Etyuhibosecyu 05.07.2026
Жаль, конечно, что я не узнал об этом, пока Lineedge существовала, а то бы Noname2331 написал, что волки превращаются в пиксельную кашу, а я бы его попросил скачать какую-нибудь бриллиантовую или Pro. . .
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru