Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
d7d1cd
204 / 133 / 49
Регистрация: 30.06.2011
Сообщений: 1,257
Завершенные тесты: 1
1

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

05.10.2017, 15:44. Просмотров 783. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.10.2017, 15:44
Ответы с готовыми решениями:

Почему есть доступ к закрытой переменной класса
Привет. Я уже было находил ответ на свой вопрос, но забыл :( Вопрос такой: есть...

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

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

Запуск программы невозможен так как на компьютере отсутствует libgcc-s-sjlj-1.dll. Попробуйте переустановить программу
Программа не запускается. Вывод: "krest_null.exe": Загружено:...

std::vector доступ по индексу vs доступ по итератору
std::vector<int> tmp; int i = 0; tmp.resize(1000000); ...

10
zss
Модератор
Эксперт С++
7257 / 6703 / 4243
Регистрация: 18.12.2011
Сообщений: 17,692
Завершенные тесты: 1
05.10.2017, 15:52 2
То, что Вы написали, практически эквивалентно
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
d7d1cd
204 / 133 / 49
Регистрация: 30.06.2011
Сообщений: 1,257
Завершенные тесты: 1
05.10.2017, 16:12  [ТС] 3
zss, спасибо большое. А получится ли в Вашем коде, скрыть класс B в классе А, оставив возможность доступа к ia?
0
zss
Модератор
Эксперт С++
7257 / 6703 / 4243
Регистрация: 18.12.2011
Сообщений: 17,692
Завершенные тесты: 1
05.10.2017, 16:30 4
Как его скрыть, если все наоборот: класс А содержится внутри В.
Может так:
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
d7d1cd
204 / 133 / 49
Регистрация: 30.06.2011
Сообщений: 1,257
Завершенные тесты: 1
05.10.2017, 16:53  [ТС] 5
Сделал так:
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
Mirmik
techpriest
623 / 204 / 55
Регистрация: 27.02.2014
Сообщений: 1,078
05.10.2017, 17:08 6
Лучший ответ Сообщение было отмечено d7d1cd как решение

Решение

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

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

Добавлено через 8 минут
Вроде понял. Метод generateB будет доступен в классе В. При его вызове он будет делать инкремент переменной ia нужного экземпляра класса А.
0
Mirmik
techpriest
623 / 204 / 55
Регистрация: 27.02.2014
Сообщений: 1,078
05.10.2017, 18:12 8
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
d7d1cd
204 / 133 / 49
Регистрация: 30.06.2011
Сообщений: 1,257
Завершенные тесты: 1
06.10.2017, 08:29  [ТС] 9
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
1000 / 695 / 159
Регистрация: 09.09.2017
Сообщений: 3,012
06.10.2017, 11:02 10
А нужен ли класс 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
d7d1cd
204 / 133 / 49
Регистрация: 30.06.2011
Сообщений: 1,257
Завершенные тесты: 1
06.10.2017, 12:44  [ТС] 11
COKPOWEHEU, класс С это пример наследника класса А. Таких наследников будет много и у каждого будут поля типа В с индивидуальными параметрами.
0
06.10.2017, 12:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.10.2017, 12:44

Почему возможно задать массив с размером -1 (почему такое вообще компилируется)?
Всем привет. Долгое время не писал на плюсах, решил пройтись по основам,...

Почему выводится в виде таблицы и почему не работает сортировка
почему выводится в виде таблицы? почему не работает сортировка? и как туда...

IDE wxDev-C++, при создании кнопки на форме она почему-то становится во весь экран, почему?
То есть ребята не смешно ни разу. Создаю форму, кидаю кнопку, ничего не...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

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