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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.72
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
#1

Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени? - C++

05.07.2011, 22:45. Просмотров 3233. Ответов 42
Метки нет (Все метки)

На самом деле ничё фантастического я не прошу, ведь:
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
template <class T>
class matrix {
        
 friend class diagonal;
 
//Вложенный класс
 public:
  class diagonal; 
 
 //Объявляем переменную такого класса 
 diagonal di;
  
 //Вот эту переменную хотелоь бы изменить в конструкторе вложенного класса
 private: 
  int per; 
 
 
};
 
 
 
template <class T>
class matrix<T>::diagonal {
 public:
  diagonal (){
   //Не изменяеится, говорится что неизвестное использование нестатической переменной per
   per= 90;
  }
};
 
 
int main () {
 matrix <int> k;
 k.di; 
}
Вот посмотрите, по-хорошему надо указать какому именно объекту дружественен класс B, чтобы потом использовать per так:
C++
1
ima_obekta_matrix.per= 90;
Но в том-то и дело, что компилятору уже известно, что объект, членом которого является di, не какой-то мифический объект, а он кокретно тот объект- куда вложен объект di. Но как компилятру объяснить, что переменную per надо брать именнно оттуда? Вот в чём вопрос!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.07.2011, 22:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени? (C++):

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

Класс: как обратиться к методу производного класса через итератор на базовый класс? - C++
Есть абстрактный и два порожденных. Хочу создать например list&lt;Base*&gt; list1; затем добавляю себе в список: ...

Класс таблиц баз данных и класс записей в таблице(реляционная таблица). Предусмотреть класс связей между таблицами - C++
Здравствуйте! Никак не могу продумать структуру этой программы. Проходим наследование, но я все равно не знаю, как его здесь применить. Как...

Создать класс “Автомагазин”, состоящей из класса ”Марки машин”. Класс “Автомагазин ”:название магазина, адрес, телефон. Класс “ Марки машин ”: марка - C++
Создать класс “Автомагазин”, состоящей из класса ”Марки машин”. Класс “Автомагазин ”:название магазина, адрес, телефон. Класс “ Марки...

Отдельно класс данных, класс формул и главный класс - C++
Здравствуйте! У меня есть три вопроса. Первый вопрос. Скажите пожалуйста! Правильный ли это подход к созданию приложений :...

Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и п - C++
Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Bers
Заблокирован
06.07.2011, 02:09 #16
kravam, приучайтесь давать красивые, красноречивые имена функциям, переменным, и тп.

А то не понятно, как этот код читать.

Цитата Сообщение от kravam Посмотреть сообщение
y.diagonal[2][1];
Что должно происходить в этой строчке?
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 06:42 #17
Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу 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
34
35
36
37
38
39
40
41
template <class T>
class matrix {
 
 friend class diagonal;
 
//Вложенный класс
 public:
 
  class diagonal;
 
 //Объявляем переменную такого класса
 diagonal di;
 
 //Вот эту переменную хотелоь бы изменить в конструкторе вложенного класса
 private:
  static int per;
 
 
};
 
template <class T> int matrix<T>::per = 50;
 
 
template <class T>
class matrix<T>::diagonal {
 public:
  diagonal (){
   //Не изменяеится, говорится что неизвестное использование нестатической переменной per
      per= 90;
  }
};
 
 
int main()
{
 
 
     matrix <int> k;
 
 
}
Цитата Сообщение от kravam Посмотреть сообщение
this->set_per ()= 90;
странная конструкция, учитывая, что this типа B*, а у В* нету никакого set_per
как вариант также можно сделать функцию статической
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
39
40
template <class T>
class matrix {
 
 friend class diagonal;
 
//Вложенный класс
 public:
    static T& set_per () {return per;};
  class diagonal;
 
 //Объявляем переменную такого класса
 diagonal di;
 
 //Вот эту переменную хотелоь бы изменить в конструкторе вложенного класса
 private:
  static int per;
 
 
};
 
template <class T> int matrix<T>::per = 50;
 
 
template <class T>
class matrix<T>::diagonal {
 public:
  diagonal (){
       set_per ()= 90;
  }
};
 
 
int main()
{
 
 
     matrix <int> k;
 
 
}
p.s. fasked в твоей предыдущей теме вроде объяснил, что между вложенными классами нет никакой взаимосвязи, которую ты пытаешься провести в своих примерах. По сути класс, в который что-то вкладывают работает как пространство имён и никак иначе. То что ты пытаешься здесь замутить, можно сделать с помощью наследования, либо с помощью статических объектов

Добавлено через 4 минуты
есть вложенный класс который является другом объемлюющего и всё это должно компилиться.
Цитата Сообщение от fasked Посмотреть сообщение
Вложенность позволяет ограничить "область действия" класса.
вот наиболее важная мысля
0
Bers
Заблокирован
06.07.2011, 11:18 #18
Цитата Сообщение от pito211 Посмотреть сообщение
доступ можно получить только к статическим объектам
У статических функций и данных внутри класса есть свои специфические задачи.

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

Если предполагается, что все данные-члены класса должны быть уникальны для каждого объекта класса, то статик-данные не нужны.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 11:41 #19
Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени
требованиям автора статические данные и методы полностью удовлетворяют.
наследование удовлетворяет требованиям из поста #13
0
Bers
Заблокирован
06.07.2011, 11:57 #20
Цитата Сообщение от pito211 Посмотреть сообщение
требованиям автора статические данные и методы полностью удовлетворяют.
наследование удовлетворяет требованиям из поста #13
Да это разве требования... так набросок предварительный.
От задачи плясать нужно.

А к чему вы наследование упомянули?

Добавлено через 4 минуты
краеугольным камнем во всей этой истории является вот такая конструктива:

y.diagonal[2][1]; // не понятно что происходит в этой строчке.

Если это действительно то, что я думаю (деталь интерфейса), то становится ясно, что задумал автор, и как это реализовать.
Если это то, что я думаю, то тут не нужны ни статики, ни наследование.
Подождём автора)
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 12:12 #21
Цитата Сообщение от Bers Посмотреть сообщение
Да это разве требования...
да, вопрос как, я и ответил как
Цитата Сообщение от Bers Посмотреть сообщение
А к чему вы наследование упомянули?
26 строка кода в посте #13
0
Bers
Заблокирован
06.07.2011, 12:26 #22
Тут видите в чем загвоздка то, что бы правильно сформулировать требования к архитектуре, нужно уметь вообще проектировать архитектуру)

А пока автор ещё только учится на архитектора, то естественно, что он и требования к архитектуре корректно сформулировать не сможет)

В таких условиях, единственное, от чего можно плясать - это от формулировки самой задачи, и от желаемого интерфейса будущего класса.
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
06.07.2011, 16:28  [ТС] #23
Короче так, друзья, вот что такое
C++
1
y.diagonal[0][0];
надеюсь тут всё понятно:
C++
1
2
3
4
matrix<int> y (6, 7);
 y.init_rand (1, 100);
y.vivod();
 y[3][4]= 99;
Названия говорят сами за себя.
Теперь: у каждой матрицы есть диагональ, и я хотел бы обращаться к элементам диагонали аналогично тому, как я обращаюсь к элементами матрицы A [stroka][stolbets]

Ну а теперь представьте что строки это диагонали. Например:

12 13 14 15
16 17 18 19
20 21 22 23

Вот матрица. В ней 6 диагоналей, вот они:
12
16 13
20 17 14
21 18 15
22 19
23

(Это, конечно, условность, они могут идти и справа налево и сверху вниз, но я решил так.)
Теперь я хочу обратиться к диагонали 3 элементу 2, я пишу
C++
1
cout<<y.diagonal[3][2];
Получаю 18. Всё просто до ужаса. (Если выход за пределы диагонали, то я вывожу соответствующее предупреждение)

Теперь главное реализовать вот это:
C++
1
y.diagonal[3][2]
////////////////////////////////////////////////////
...В наличии есть функция, а в ней формула которая преобразует ДИАГОНАЛЬНЫЕ координаты [2][3] в СТАНДАРТНЫЕ координаты [1][2], я её накропал сам
////////////////////////////////////////////////////

Собсно,размышляя сегодня на лоне природы о бренности всего земного, я пришёл к выводу, что я сию херь реализую без труда так:
C++
1
y.diagonal[B]([/B]3,2[B])[/B]
Но это не наш метод, как говорится.

И ещё: не хочется иметь два массива: собственно матрицу и массив диагоналей. Тогда, наверное, я используя перегрузку операторов [] всё-таки получу нужный мне элемент. Но! Тогда изменив элемент матрицы, например:
C++
1
y[3][4]= 99;
Я должен буду позаботиться и об изменении другого элемента- элемента вектора в массиве векторов (диагональ это у меня вектор). А это тоже не наш метод. Лучше иметь один массив и с ним работать так
C++
1
y[3][4]= 99;
и так:
C++
1
y.diagonal[3][2]
Потом я отпишусь по пунктам ещё.

Добавлено через 10 минут
Ребята, я наперепутывал всё с координатами, извиняюсь. Короче диагонали считаются с левого верхнего угла (нулевая диагональ) и пошли вниз до правого нижнего угла, а элементы диагоналей считаются слева направо и соответственно снизу вверх
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 16:31 #24
Цитата Сообщение от kravam Посмотреть сообщение
Всё просто до ужаса
не смеши. Прежде чем пользоваться матрицей человек должен будет прочитать мануал, потому что данный порядок
Цитата Сообщение от kravam Посмотреть сообщение
12
16 13
20 17 14
21 18 15
22 19
23
неочевиден
тем более ты уже сам запутался

занялся бы чем-нибудь полезным. Почитай лучше страуструпа, если с классами и абстракцией данных проблемы, мейерса, александреску. У тебя какая-то нездоровая мания решать простые задачи через задницу и какой с этого толк? Помоему пустая трата времени
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
06.07.2011, 16:39  [ТС] #25
Да, человек должен будет прочитать мануал. Данный порядок неочевиден. Но ты представляешь, я расчитываю на людей, умеющих читать. По крайней мере я читать умею, а мне это пригодится. А я запутался не тем более, просто ошибся чуток с координатами. Короче, ты не знаешь.
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 16:47 #26
Цитата Сообщение от kravam Посмотреть сообщение
Но ты представляешь, я расчитываю на людей, умеющих читать
умеют то многие, но врядли ты хоть одного найдёшь, кто захочет пользоваться матрицей для которой ещё что-то читать надо и запоминать. Так что это всё сугубо "для себя" для своих "домашних" проектов
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
06.07.2011, 16:48  [ТС] #27
Пусть так.
0
Bers
Заблокирован
06.07.2011, 17:01 #28
Цитата Сообщение от kravam Посмотреть сообщение
Да, человек должен будет прочитать мануал. Данный порядок неочевиден. Но ты представляешь, я расчитываю на людей, умеющих читать. По крайней мере я читать умею, а мне это пригодится. А я запутался не тем более, просто ошибся чуток с координатами. Короче, ты не знаешь.
Я все никак не могу понять, какой именно вам нужен интерфейс, и что методы интерфейса конкретно должны делать.

Но главное, что сейчас не понятно, какие, и как вы планируете хранить данные.

Давайте сделаем по взрослому:

Сделайте диздок класса Матрицы.
Обычный текстовый файл, в котором по пунктам с толком с расстановкой будит описано:
- задача, которую реализует класс,
- интерфейс класса. Подробно расписав каждый метод. Желательно с примерами.

Отдельно опишите предполагаемые внутренности класса,
какие данные будут храниться, как они будут храниться,
в частности, если Матрица содержит внутри Диагональ, то опять таки, опишите задачи, которые выполняет диагональ, её интерфейс (тоже подробно расписанный по каждому паблик-методу)

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

/зы сделать доступ к данным через Диагональ не проблема, проблема не спутать понятие "деталь интерфейса", и "частные данные"
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
07.07.2011, 17:27  [ТС] #29
Если всё понятно и не отвратительно, тогда добавлю сюда свою задачу. Всё работает и вопросов у меня не вызывает, на вашем месте я бы реализацию не смотрел.
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <typeinfo>
#include <time.h>
 
//Класс matrix чтобы решать задачи с матрицами; интерфейс
 
template <class T>
class matrix {
 public:
 
  //Кнструтор по умолчанию создаёт матрицу из 2-х строк и одного столбца; ничем не инициализирует
  matrix ();        
 
  //Конструктор просто создаёт матрицу, выделяет место под строи и столбцы, но не инициализирует их
  //В деструкторе, понятно, эта память освободится
  matrix (int x, int y);    
 
 
  //А это деструктор, освобождает на хер всю занятую память
  ~matrix ();        
 
  //Инициализация матрицы рандомно значениями от x до y влючительно
  //если значения типа double, то тоже будет всё нормально, после запятой будет два знака
  void init_rand (int x, int y); 
 
  //Это вот вывод матрицы
  void vivod ();
 
  //Возвращаает количество строк
  int get_kol_vo_strok () {return kol_vo_strok;};
  //... и количество столбцов
  int get_kol_vo_stolb () {return kol_vo_stolb;}
 
  //Преобразования типа, эта херь позволит перегрузить оператор [][]
  //Это я сам придумал не без подачи ребят
  operator T**() {return p;};
 
 
 private:
 
 //Количество строк, количество столбцов
  int kol_vo_strok;         
  int kol_vo_stolb;         
 
 
  //Динамический мссив из указателей на указатели на T
  T**p;
};
 
 
//Р Е А Л И З А Ц И Я
template <class T>
matrix<T>::matrix () {
 kol_vo_strok= 2; kol_vo_stolb= 1;
 p= new T* [kol_vo_strok];
 p[0]= new T;
 p[1]= new T;
};        
 
template <class T>
matrix<T>::matrix (int x, int y):kol_vo_strok(x), kol_vo_stolb(y) {
 p= new T* [x];
 for (int i= 0; i< x; i++) {
  p[i]= new T [y];
 }
};        
 
template <class T>
matrix<T>::~matrix () {
 for (int i= 0; i< kol_vo_strok; i++)
  delete [] p[i];
 delete [] p;
};        
 
template <class T>
void matrix<T>::init_rand (int x, int y) {
 srand (time(0));
 double temp;
 for (int i= 0; i< get_kol_vo_strok(); i++) {
  for (int j = 0; j< get_kol_vo_stolb(); j++) {
   p[i][j]= rand()%(y- x+ 1)+ x;
   if (typeid(p[i][j])== typeid (temp)) {
    if (p[i][j]!= y) {
     p[i][j]+= (T)rand()/(RAND_MAX+1);;
    }
   }
  }
 }
}
 
template <class T>
void matrix<T>::vivod () {
 double temp;
 for (int i= 0; i< get_kol_vo_strok(); i++) {
  for (int j = 0; j< get_kol_vo_stolb(); j++) {
   if (typeid(p[i][j])== typeid (temp))
    printf ("%.2f ", (double)p[i][j]);  
   else
    printf ("%3d ", p[i][j]);  
   }
   printf ("\n");
 }
}
//К О Н Е Ц   Р Е А Л И З А Ц И И
 
 
 
 
int main () {
 
 matrix <int> k;
 
 matrix<int> y (6, 7);
 y.init_rand (1, 100);
 y.vivod();
 printf ("\n");  
 
 //Благодаря моей дури "operator T**() {return p;};" эта херь корректна:
 printf ("%d\n", y[3][4]);  
 y[3][4]= 99;
 
 y.vivod();
 printf ("kol_vo_strok=  %d\n",  y.get_kol_vo_strok());  
 printf ("kol_vo_stolb=  %d\n",  y.get_kol_vo_stolb());  
 
 getchar (); 
 
}
0
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
07.07.2011, 19:01 #30
Цитата Сообщение от kravam Посмотреть сообщение
operator T**() {return p;};
сомнительная строка. Пользователь запросто может получить доступ к данным и забить на весь интерфейс. Нарушением инкапсуляции попахивает

Добавлено через 10 минут
Цитата Сообщение от kravam Посмотреть сообщение
if (typeid(p[i][j])== typeid (temp))
зачем проверять каждый элемент матрицы, что он дабл? насколько я понимаю матрица однородная, достаточно проверить один раз и temp нигде не используется

Добавлено через 1 час 6 минут
кстати ты в конструкторах используешь разные формы new(строки58-59 и 66), а в деструкторе применяешь исключительно delete[]
это может привести к печальным последствиям
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.07.2011, 19:01
Привет! Вот еще темы с ответами:

Создайте класс, в котором есть ostream& operator<<. Класс должен содержать очередь с приоритетом - C++
Создайте класс, в котором есть ostream&amp; operator&lt;&lt;. Класс должен содержать очередь с приоритетом. Создайте генератор — заполнитель очереди...

Как преобразовать указатель на класс к указателю на асбтрактный класс? - C++
Но тут есть одна тонкость- два промежуточных класса. Вот код, надеюсь всё из него понятно. #include &lt;stdio.h&gt; ...

Как создать класс со вложенной структурой указателей на класс? - C++
В классе Concept хранится массив (точнее map) структур Rel. Сама же структура Rel должна содержать указатели на класс Concept. ...

Разработать производный от абстрактного класса Figure класс и класс, производный от производного - C++
Разработать базовый абстрактный класс Figure с пустым виртуальным методом print для вывода в дальнейшем полной информации об объекте: ...


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

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

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