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

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

05.07.2011, 22:45. Показов 8809. Ответов 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,705
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,705
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,705
06.07.2011, 16:48  [ТС]
Пусть так.
0
Заблокирован
06.07.2011, 17:01
Цитата Сообщение от kravam Посмотреть сообщение
Да, человек должен будет прочитать мануал. Данный порядок неочевиден. Но ты представляешь, я расчитываю на людей, умеющих читать. По крайней мере я читать умею, а мне это пригодится. А я запутался не тем более, просто ошибся чуток с координатами. Короче, ты не знаешь.
Я все никак не могу понять, какой именно вам нужен интерфейс, и что методы интерфейса конкретно должны делать.

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

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

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

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

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

/зы сделать доступ к данным через Диагональ не проблема, проблема не спутать понятие "деталь интерфейса", и "частные данные"
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
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,705
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,705
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,705
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,705
07.07.2011, 20:12  [ТС]
silent_1991, чё уж так-то уж, я ведь и сам мог delete p написать и компильнуть. Я просил пример из учебника какого-нибудь.
Но как-бы то ни было, у Павловской я нашёл, что да, можно delete p, а можно delete [] p;
При чём строго-настрого сказано, что если память выделена под массив, то надо второй вариант.
Иначе удалится только память под первый объект, да это и так понятно.

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

Но так-то я чел дисциплинированный, сказано писать без квадратных скобок, буду писать без квадратных скобок. Дабы приучать себя к порядку.
0
Эксперт С++
 Аватар для grizlik78
2383 / 1667 / 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
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru