Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/35: Рейтинг темы: голосов - 35, средняя оценка - 4.63
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701

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

05.07.2011, 22:45. Показов 8234. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.07.2011, 22:45
Ответы с готовыми решениями:

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

Как правильно передавать параметры из класса А в класс С через класс B?
Всем привет! Пишу игру - Морской бой! Есть класс Game. Также есть класс Battlefield (модель поля, где корабли располагаются). Но нам нужно...

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

42
 Аватар для pito211
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 12:12
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Bers Посмотреть сообщение
Да это разве требования...
да, вопрос как, я и ответил как
Цитата Сообщение от Bers Посмотреть сообщение
А к чему вы наследование упомянули?
26 строка кода в посте #13
0
Заблокирован
06.07.2011, 12:26
Тут видите в чем загвоздка то, что бы правильно сформулировать требования к архитектуре, нужно уметь вообще проектировать архитектуру)

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

В таких условиях, единственное, от чего можно плясать - это от формулировки самой задачи, и от желаемого интерфейса будущего класса.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
06.07.2011, 16:28  [ТС]
Короче так, друзья, вот что такое
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
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 16:31
Цитата Сообщение от kravam Посмотреть сообщение
Всё просто до ужаса
не смеши. Прежде чем пользоваться матрицей человек должен будет прочитать мануал, потому что данный порядок
Цитата Сообщение от kravam Посмотреть сообщение
12
16 13
20 17 14
21 18 15
22 19
23
неочевиден
тем более ты уже сам запутался

занялся бы чем-нибудь полезным. Почитай лучше страуструпа, если с классами и абстракцией данных проблемы, мейерса, александреску. У тебя какая-то нездоровая мания решать простые задачи через задницу и какой с этого толк? Помоему пустая трата времени
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
06.07.2011, 16:39  [ТС]
Да, человек должен будет прочитать мануал. Данный порядок неочевиден. Но ты представляешь, я расчитываю на людей, умеющих читать. По крайней мере я читать умею, а мне это пригодится. А я запутался не тем более, просто ошибся чуток с координатами. Короче, ты не знаешь.
0
 Аватар для pito211
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
06.07.2011, 16:47
Цитата Сообщение от kravam Посмотреть сообщение
Но ты представляешь, я расчитываю на людей, умеющих читать
умеют то многие, но врядли ты хоть одного найдёшь, кто захочет пользоваться матрицей для которой ещё что-то читать надо и запоминать. Так что это всё сугубо "для себя" для своих "домашних" проектов
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
06.07.2011, 16:48  [ТС]
Пусть так.
0
Заблокирован
06.07.2011, 17:01
Цитата Сообщение от kravam Посмотреть сообщение
Да, человек должен будет прочитать мануал. Данный порядок неочевиден. Но ты представляешь, я расчитываю на людей, умеющих читать. По крайней мере я читать умею, а мне это пригодится. А я запутался не тем более, просто ошибся чуток с координатами. Короче, ты не знаешь.
Я все никак не могу понять, какой именно вам нужен интерфейс, и что методы интерфейса конкретно должны делать.

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

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

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

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

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

/зы сделать доступ к данным через Диагональ не проблема, проблема не спутать понятие "деталь интерфейса", и "частные данные"
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
07.07.2011, 17:27  [ТС]
Если всё понятно и не отвратительно, тогда добавлю сюда свою задачу. Всё работает и вопросов у меня не вызывает, на вашем месте я бы реализацию не смотрел.
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
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
07.07.2011, 19:01
Цитата Сообщение от kravam Посмотреть сообщение
operator T**() {return p;};
сомнительная строка. Пользователь запросто может получить доступ к данным и забить на весь интерфейс. Нарушением инкапсуляции попахивает

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

Добавлено через 1 час 6 минут
кстати ты в конструкторах используешь разные формы new(строки58-59 и 66), а в деструкторе применяешь исключительно delete[]
это может привести к печальным последствиям
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
07.07.2011, 19:03  [ТС]
А как надо освобождать память?
0
 Аватар для pito211
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
07.07.2011, 19:09
можно проверять kolvo_strok и kolvo_stolbcov и в зависимости от него вызывать соответсвующий delete, либо в конструкторе по умолчанию выделять наверное так
C++
1
2
 p[0]= new T[1];
 p[1]= new T[1];
второй вариант выглядит предпостительнее, так как не надо никаких ветвлений в деструкторе
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
07.07.2011, 19:30  [ТС]
Цитата Сообщение от pito211 Посмотреть сообщение
можно проверять kolvo_strok и kolvo_stolbcov и в зависимости от него вызывать соответсвующий delete
В отличие от операции new, для которой можно определить разные модификации в зависимости от числа и типов аргументов, операция delete существует только в единственном варианте:
void operator delete (void* addr);
0
 Аватар для pito211
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
07.07.2011, 19:47
то что ты написал никак не противоречит моему утверждению, а оно такого:
если выделял new[] то удаляй delete[]
если выделял new то удаляй delete
а в ссылке которую ты привёл речь идёт об определении собственных new и delete
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
07.07.2011, 19:48
kravam, ага, щас... Для каждого new надо вызывать соответствующий delete. Создали одиночную область памяти с помощью new - вызвали delete, создали массив с помощью new [] - обязательно надо вызвать delete [].
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
07.07.2011, 19:53  [ТС]
ОК, не покажешь, где описан пример использования delete так
C++
1
delete p;
Я вот искал-искал и не нашёл, а что нашёл, так получается не то.

Добавлено через 1 минуту
И ещё я могу книжки назвать, где это не описано.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
07.07.2011, 19:55
kravam,
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
#include <iostream>
 
class Foo
{
public:
    virtual void vfunc() const
    {
        std::cout << "Foo::vfunc()" << std::endl;
    }
};
 
class Bar : public Foo
{
public:
    virtual void vfunc() const
    {
        std::cout << "Bar::vfunc()" << std::endl;
    }
};
 
int main()
{
    Foo *f1 = new Foo ();
    Foo *f2 = new Bar ();
 
    f1->vfunc();
    f2->vfunc();
 
    delete f1;
    delete f2;
 
    return 0;
}
0
 Аватар для pito211
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
07.07.2011, 19:56
а чё там может не получится? исключений delete вроде как не вызывает, главное чтобы указатель был валидным, можно и нулевой
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,701
07.07.2011, 20:12  [ТС]
silent_1991, чё уж так-то уж, я ведь и сам мог delete p написать и компильнуть. Я просил пример из учебника какого-нибудь.
Но как-бы то ни было, у Павловской я нашёл, что да, можно delete p, а можно delete [] p;
При чём строго-настрого сказано, что если память выделена под массив, то надо второй вариант.
Иначе удалится только память под первый объект, да это и так понятно.

Но подобных строгих ограничений не наложено если память выделена под один элемент. int * p= new x;
То есть сказано, что надо освободить так: delete p.
Я тут думал-думал чё страшного может произойти, если я буду писать delete [] p чё и никак не придумал. Ничего.

Но так-то я чел дисциплинированный, сказано писать без квадратных скобок, буду писать без квадратных скобок. Дабы приучать себя к порядку.
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
07.07.2011, 20:17
Цитата Сообщение от kravam Посмотреть сообщение
Я тут думал-думал чё страшного может произойти, если я буду писать delete [] p чё и никак не придумал. Ничего.
За тебя это страшное вполне могут придумать создатели компилятора
Т.к. в стандарте говорится, что удаление массива с помощью delete, как и удаление одиночного объекта с помощью delete [] это "behavior is undefined"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.07.2011, 20:17
Помогаю со студенческими работами здесь

Наследование. Каким образом через ссылку на класс-родитель можно получить доступ к классу-потомку?
&quot;Ведь по ссылке на объект базового класса можно обращаться к объекту производного класса, т.е. к объекту, на который ссылается переменная...

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

Класс: Описать класс Points, затем производный от него Circle
Задание: Описать класс Points, затем производный от него Circle. Создать динамический массив указателей на объекты класса Circle и...

Класс: Разработать абстрактный класс класс Point для задания координаты...
Всем привет, помогите пожалуйста решить задачу, я уже всю голову сломал, не знаю как решить... Разработать абстрактный класс класс...

3 класса. Родительский класс - класс животных. Два класса наследника: Гиппопотамы и Зебры. Выбор структуры данных
Добрый День. Есть задача. Есть 3 класса. Родительский класс - это класс животных. Он абстрактный и содержит метод в котором считается...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru