Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712

Почему невозможен доступ

05.10.2017, 15:44. Показов 1185. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Есть такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A
{
 private:
 int ia;
 
 protected:
 class B
  {
   private:
   int ib;
 
   public:
   B() : ib(ia++) {} /* Вопрос по этой строке */
  };
 
 public:
 A() : ia(0) {}
};
Вопрос в следующем. Почему в обозначенной строке возникает ошибка о том, что к переменной ia можно обратиться только через объект класса A?
Рассуждаю так. Создать объект класса B можно только в классе, унаследованном от A. Соответственно, при этом всегда будет создаваться переменная ia. Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class C : public A
{
 private:
 B b;
 
 public:
 C()
 /* Первое. Отработает конструктор A() и, соответственно, переменная ia будет создана */
 /* Второе. Начнет работать конструктор B() и доступ к ia, по идее, должен быть */
 {
 }
};
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.10.2017, 15:44
Ответы с готовыми решениями:

Почему есть доступ к закрытой переменной класса
Привет. Я уже было находил ответ на свой вопрос, но забыл :( Вопрос такой: есть след. класс: class Test { public: void F(Test t) {...

Почему извне есть доступ к приватному nested-классу?
class Test { struct PrivateType { PrivateType() {} }; public: void func(PrivateType) {} }; int main() {

Почему не могу получить доступ к protected полям из дочернего класса?
Пытаюсь получить доступ к ships из дочернего класса Referee, но не получается. В чем ошибка? class Player { protected: ...

10
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
05.10.2017, 15:52
То, что Вы написали, практически эквивалентно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A
{
 private:
 int ia;
 
 protected:
 
 
 public:
 A() ia(0)  {}
};
class B
  {
   private:
   int ib;
 
   public:
   B() : ib(ia++) {} /* Вопрос по этой строке */
  };
Только у Вас класс B виден исключительно внутри класса A.
И каким боком класс B относится к ia??????????

Если имелось ввиду наследование, то Вам надо что-то типа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
 protected:
  static int ia;
  public:
 A() {}
};
class B:public A
  {
   private:
   int ib;
 
   public:
   B() { ib=ia++;} /* Вопрос по этой строке */
  };
int A::ia=0;
2
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
05.10.2017, 16:12  [ТС]
zss, спасибо большое. А получится ли в Вашем коде, скрыть класс B в классе А, оставив возможность доступа к ia?
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,245
05.10.2017, 16:30
Как его скрыть, если все наоборот: класс А содержится внутри В.
Может так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SecretClass
{
 protected:
  static int ia;
};
class A:public SecretClass
  {
   private:
   int ib;
 
   public:
   A() { ib=ia++;}
  };
int SecretClass::ia=0;
int main()
{
    A b1,b2,b3;
};
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
05.10.2017, 16:53  [ТС]
Сделал так:
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 A
{
 private:
 static int ia;
 
 protected:
 class B
  {
   private:
   int ib;
 
   public:
   B() { ib = A::ia++; }
  };
 
 public:
 A() { ia = 0;}
};
 
int A::ia = 0;
 
class C : public A
{
 private:
 B b1;
 B b2;
 
 public:
 C() {}
};
Но возникает другая проблема. Объекты классов, унаследованных от A, будут потоконебезопасны, так как переменная ia одна на все объекты всех классов, унаследованных от А. Можно ли реализовать то, что мне требуется, не используя статическую переменную?
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
05.10.2017, 17:08
Лучший ответ Сообщение было отмечено d7d1cd как решение

Решение

Класс B не знает, от какому конкретно объекту A нужно модифицировать переменную. Передайте ему в конструктор указатель на этот объект.

Добавлено через 3 минуты
С другой стороны, вы можете в классе A реализовать protected метод generateB(), переменную ai инкрементировать в генераторе generateB, а в наследнике использовать не конструктор B непосредственно, а генератор. Это будет академичненько.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
05.10.2017, 18:01  [ТС]
Mirmik, Вы имеете ввиду использовать метод для получения значения и инкремента переменной ia? Но ведь в этом случае все равно надо будет передавать в класс В указатель на объект А. Или нет? Запутался уже...

Добавлено через 8 минут
Вроде понял. Метод generateB будет доступен в классе В. При его вызове он будет делать инкремент переменной ia нужного экземпляра класса А.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
05.10.2017, 18:12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A {
  int ai;
 
protected:
  class B { ... };
 
  B generateB() {
    ai++;
    return B();
  }
};
 
class C : public A {
...
void func() {
  B b = generateB();
}
...
}
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
06.10.2017, 08:29  [ТС]
Mirmik, решил, все-таки, воспользоваться Вашим первым советом, а именно передавать в конструктор класса B указатель на A:
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
class A
{
 private:
 int ia;
 
 protected:
 class B
  {
   private:
   int ib;
 
   public:
   B(int i, A* a)
    {
     ib = a->ia;
     a->ia += i;
    }
  };
 
 public:
 A() : ia(0) {}
};
 
 
class C : public A
{
 private:
 B b1;
 B b2;
 
 public:
 C() : b1(10, this), b2(20, this) {}
};
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,928
06.10.2017, 11:02
А нужен ли класс C?
Возможно, стоит передавать ia не по значению а по указателю?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A
{
 private:
 int ia;
 
 protected:
 class B
  {
   private:
   int *ib;
 
   public:
   B(int i, A* a)
    {
     ib = &(a->ia);
     (*ib)++;
    }
  };
  B b1, b2;
 public:
 A() : b1(10,this), b2(10,this) {}
};
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
06.10.2017, 12:44  [ТС]
COKPOWEHEU, класс С это пример наследника класса А. Таких наследников будет много и у каждого будут поля типа В с индивидуальными параметрами.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.10.2017, 12:44
Помогаю со студенческими работами здесь

Почему я могу легально получить доступ к private полю у ссылочного типа на класс?
Здравствуйте, я недавно решила написать длинную арифметику по памяти (годовой давности) и как можно быстрее. В итоге, я получила такой код:...

Почему у методов класса есть доступ к закрытым полям другой переменной такого же типа?
Привет всем. Объясните, кто знает, почему есть доступ к приватным полям аргумента такого же типа в методе класса. class Point { ...

"Доступ к ликвидированному объекту невозможен" - почему?
Здравствуйте! У меня есть 2 формы. Первая форма запускает вторую форму вот таким вот образом: Form2 f2 = new Form2(); ...

Доступ к закрытому потоку невозможен
Здравствуйте. есть функция , которая возвращает Stream. Когда я в переменную Stream заношу результат этой функции - далее не могу с ней...

Доступ к закрытому потоку невозможен
Вылетает ошибка: "Доступ к закрытому потоку невозможен." MemoryStream _tempMem; _tempMem.Position = 0; string subject =...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru