Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562

Может ли объект-член, или объект-элемент достучаться к содержащему его?

14.03.2014, 09:27. Показов 5455. Ответов 58
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Предположим,
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
{
 ...
};
class B
{
 ....
 A a;
...
};
class C
{
 ...
 A *a;
 ...
}
...
B b1;
B *b2;
C c;
size_t i;
...
. Может ли b1.a достучаться до b1, b2[i].a к b2[i], а c.a[i] - до c? Данные по c.a и b2 могут перемещаться reallocом.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.03.2014, 09:27
Ответы с готовыми решениями:

Если объект константный, означает ли это, что ни один его член-элемент или член-метод не изменится?
Назрел такой вопрос: Если объект константный это означает, что ни один его член-элемент или член-метод не изменится или только некоторые из...

Недопустимый неполный тип , или как передать в функцию указатель на объект класса , или просто объект
Други мои , кодеры. Не могу я ни как передать в функцию объект класса , или что еще лучше(для меня , так как учусь работать с указателями)...

Основы: указатель на объект или объект, что выбрать?
Не до конца понимаю (или вообще не понимаю) когда лучше использовать указатель на объект, а когда объект. Например: // есть класс ...

58
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.03.2014, 17:34  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Alex5 Посмотреть сообщение
B A::* q; // указатель на член класса ( член, имеющий тип B )
* * q = &A::b1; // *0x00000008
Это что за синтаксис такой?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
14.03.2014, 17:43
taras atavin, обычный для указателей на члены класса. Это по сути как раз те самые смещения. Поэтому их получают через определение класса
&A::b1
, не через объект.
А вот reinterpret_cast в этом случае - нехорошо. Пример не учитывает выравнивание, к тому же компилятор для не standard-layout классов может менять местами поля в целях оптимизации. Ну и достаточно просто добавить в такой класс еще одно поле и не провести соответствующих изменений в коде доступа к полям, то все смещения "поплывут".
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.03.2014, 17:45  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
taras atavin, обычный для указателей на члены класса. Это по сути как раз те самые смещения. Поэтому их получают через определение класса
&A::b1
, не через объект.
Расшифруй как для нуба в кубе.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
14.03.2014, 18:04
taras atavin,
Есть объект типа А. Назовем его obj.
У него естественно есть адрес.
Адрес есть и у каждого его поля. Указатель на это поле можно получить двумя способами. Первый способ - это получить указатель на объект поля.
C++
1
int * pA = &obj.a;
А можно (второй способ) получить смещение относительно базы.
C++
1
int A::* offsetA = &A::a;
Ну вот такая запись, она означает, что мы взяли относительный указатель на поле типа int в классе А.
Для доступа по этому смещению нам нужна база. Это базой может служить непосредственно объект типа А.
C++
1
2
A obj;
int v = (obj.*offsetA);
тут мы получили значение поля а, смещение которого мы запомнили в offsetA, у объекта obj.
либо, можно использовать для этого указатель:
C++
1
2
A * pObj;
int v = (pObj->*offsetA);
Для указатель на методы те же правила. Только в отличие от данных, нельзя получить абсолютный адрес метода, только вот такой относительный.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.03.2014, 18:07  [ТС]
Нда. А кто мешает юзать имена полей и поручить смещения компилятору?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
14.03.2014, 18:14
taras atavin, никто. Просто иногда это бывает полезно.

Добавлено через 6 минут
Лично я не находил применения таким указателям на данные. Но зато использовал указатели на методы (у них синтаксис похож, только параметры еще добавляются). Это полезно при реализации делегатов.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.03.2014, 18:23  [ТС]
Цитата Сообщение от Alex5 Посмотреть сообщение
B A::* q; // указатель на член класса ( член, имеющий тип B )
* * q = &A::b1; // *0x00000008
int* pInt2 = reinterpret_cast<int*>( &q ); // *pInt2 == 8 , т.е. sizeof(A::m) + sizeof(A::n)
// чтобы получить адрес объекта-агрегата, из this вычитаем 8
* * void* parent = reinterpret_cast<char*>(this) - *pInt2;
* * return parent;
А откуда известно, что this указывает именно на b1? Что выведет:
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
struct B
{
    void* func();
};
 
struct A
{
    int m; 
    int n;
    B b1;
    B b2;
};
 
void* B::func()
{
    B A::* q; // указатель на член класса ( член, имеющий тип B )
    q = &A::b1; //  0x00000008
 
    int* pInt2 = reinterpret_cast<int*>( &q ); // *pInt2 == 8 , т.е. sizeof(A::m) + sizeof(A::n)
 
    // чтобы получить адрес объекта-агрегата, из this вычитаем 8
    void* parent = reinterpret_cast<char*>(this) - *pInt2;
    return parent;
}
 
int main()
{
    A a;
    cout << "\n &a    " << &a << endl;
 
    void* p = a.b2.func();
    cout << "\n result of  a.b2.func()  " << p << endl;
 
    // ... 
}
? А ведь по условию функцией может владеть даже элемент динамического массива.
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
14.03.2014, 20:18
Цитата Сообщение от DrOffset Посмотреть сообщение
Пример не учитывает выравнивание, к тому же компилятор для не standard-layout классов может менять местами поля в целях оптимизации.
Данный пример как раз учитывает выравнивание.
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну и достаточно просто добавить в такой класс еще одно поле ...
Давайте посмотрим.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
/* добавим поле char, больше никаких изменений в коде нет (см. сообщение #20) */
struct A
{
    char c; 
    // ... 
};
/* Результат: 
 
 &a    0019F9EC
 
 result of  a.b1.func()  0019F9EC
 
*/
Цитата Сообщение от DrOffset Посмотреть сообщение
А вот reinterpret_cast в этом случае - нехорошо
Это верно, но по другой причине. А именно, указатель на член класса определяет смещение поля объекта.
Но вряд ли можно полагаться на то, что он просто равен смещению. Зависимость может быть какой-то другой.
(Вариант 1. Указатель на член класса равен смещению+1. Значение 0 зарезервируем для недействительного указателя.)
(Вариант 2. Указатель на член класса равен смещению. Недействительный указатель: 0xFFFFFFFF.)
(Другие варианты ... )
Так что, если использовать .* или ->* компилятор всё расшифрует правильно. А при использовании reinterpret_cast возникнет ошибка.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
14.03.2014, 23:29
Цитата Сообщение от Alex5 Посмотреть сообщение
Данный пример как раз учитывает выравнивание.
В принципе было бы достаточно этой фразы. Действительно, учитывает. А "магическая" константа была в комментарии, а не в коде, на что я и не обратил внимания
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 07:37  [ТС]
Данный пример не учитывает, что однотипных членов может быть несколько.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 07:48  [ТС]
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
#include <limits>
#include <iostream>
#include <fstream>
class A;
class B;
class A
{
 public:
  B *func();
};
class B
{
 public:
  A a1;
  A a2;
};
B* A::func ()
{
 A B::* q;
 int *Offcet;
 B *Parent;
 q = &B::a1;
 Offcet=reinterpret_cast<int*>( &q );
 Parent = reinterpret_cast<B*>(reinterpret_cast<char*>(this) - *Offcet);
 return Parent;
}
int main ()
{
 B b;
 std::cout<<(void*)&b<<std::endl;
 std::cout<<(void*)b.a1.func()<<std::endl;
 std::cout<<(void*)b.a2.func()<<std::endl;
 return 0;
}
Миниатюры
Может ли объект-член, или объект-элемент достучаться к содержащему его?  
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 07:49  [ТС]
На скрине видно, что функция не знает, для какого именно члена вызвана на самом деле и не может определить адрес искомого объекта.
0
Заблокирован
15.03.2014, 07:54
Цитата Сообщение от taras atavin Посмотреть сообщение
Данный пример не учитывает, что однотипных членов может быть несколько.
расскажи нам как это?
Может ли объект-член, или объект-элемент достучаться к содержащему его?
может, если ты поместишь в него нужный указатель .
Иначе никак не может
DrOffset,
Что там о виртуальных функциях в твоих примерах?
Откуда дочерний объект уверен, что он является полем класса "А"? - в твоих примерах именно так. Т.е. поместить его в другой класс я не могу.
Унылый вариант.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 07:57  [ТС]
А ведь есть ещё такие пакости:
1. Класс A является типом членов одновременно нескольких других классов.
2. Класс A является типом элементов реализованных на указателях динамических массивов и индекс элемента членам самого класса A не известен.
3. Экземпляр A может быть и обычным объектом, а не частью другого объекта.

Добавлено через 1 минуту
Цитата Сообщение от rrrFer Посмотреть сообщение
Откуда дочерний объект уверен, что он является полем класса "А"? - в твоих примерах именно так. Т.е. поместить его в другой класс я не могу.
А ничего, что даже в стартовом посте фигурируют одновременно два класса, содержащих его экземпляры?
0
Заблокирован
15.03.2014, 07:58
Цитата Сообщение от taras atavin Посмотреть сообщение
На скрине видно, что функция не знает, для какого именно члена вызвана на самом деле и не может определить адрес искомого объекта.
Да ты в код то посмотри:
C++
1
q = &B::a1;
С чего ты вообще взял что оно должно определять "адрес искомого объекта"?
Я ж грю, код унылый и ни разу не в тему.
Оно вернет нужный тебе адрес, если объект класса В является членом именно класса А, и только для поля a1 (да и именно с таким именем).
ИМХО автор кода не знает куда приткнуть свои навыки говнокодинга, поэтому вот..

А по теме, я уже сказал. Помещай в дочерний класс указатель на родительский. Только так.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 08:07  [ТС]
Цитата Сообщение от rrrFer Посмотреть сообщение
Да ты в код то посмотри:
Код C++
1
q = &B::a1;
Я то как раз сразу это разглядел, а некоторым объяснять приходится, причём, на скринах.

Добавлено через 51 секунду
Задача не решена.

Добавлено через 5 минут
И похоже не имеет на c++ качественного решения, которое бы не страдало возможностью порчи адреса агрегирующего объекта: можно завести член
C++
1
void *parent;
, но его придётся исправлять при каждом перемещении агрегирующего объекта, для чего придётся этот член открыть в public, а тогда к нему будет доступ откуда угодно и можно будет его модифицировать без какой либо связи с перемещением агрегирующего объекта. Здесь нужны встроенные языковые средства, а parent должен модифицироваться только неявно.
0
Заблокирован
15.03.2014, 08:13
И похоже не имеет на c++ качественного решения, которое бы не страдало возможностью порчи адреса агрегирующего объекта: можно завести член
Чето я не понял кто там тебе адрес портит (или может испортить). Приведи пример (код целиком, а не кусками, мне лень дописывать)..
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 10:02  [ТС]
Цитата Сообщение от rrrFer Посмотреть сообщение
Чето я не понял кто там тебе адрес портит (или может испортить). Приведи пример (код целиком, а не кусками, мне лень дописывать)..
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
#ifndef TARRAY_HPP_INCLUDED
#define TARRAY_HPP_INCLUDED
//=====================================================================================================================================================================================================
#include <malloc.h>
#include <limits>
//=====================================================================================================================================================================================================
template <typename TBase> class TArray
{
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 private:
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  size_t                                    Count;
  TBase                                    *Data;
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 public :
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                            TArray                           (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                            TArray                           (const
                                                                              TArray                           &Original          );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                           ~TArray                           (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      ReSize                           (size_t                            Count             );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      Empty                            (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      Filled                           (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                            operator size_t                  (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  TBase                                    &operator []                      (size_t                            Index             );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  TArray                                   &operator =                       (const
                                                                              TArray                           &Original          );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      Addition                         (const
                                                                              TBase                            &s                 );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      Addition                         (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  TBase                                    &Last                             (                                                    );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  TArray                                    SubArray                         (size_t                            Start             ,
                                                                              size_t                            End               );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      operator ==                      (const
                                                                              TArray                           &Compare           );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  bool                                      operator !=                      (const
                                                                              TArray                           &Compare           );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  size_t                                    Find                             (const
                                                                              TBase                            &s                 );
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
};
//=====================================================================================================================================================================================================
template <typename TBase>
TArray <TBase>        ::                    TArray                           (                                                    )
{
 Count=0;
 Data =NULL;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>        ::                    TArray                           (const
                                                                              TArray                           &Original          )
{
 TBase *Source;
 TBase *Target;
 if (Original.Count>0)
 {
  Data=(TBase*)malloc(_msize(Original.Data));
  if (Data!=NULL)
  {
   Count=_msize(Data)/sizeof(TBase);
   for (Source=Original.Data+Count-1, Target=Data+Count-1; Target>=Data; --Source, --Target)
   {
    new (Target) TBase;
    *Target=*Source;
   }
  }
  else
  {
   Count=0;
  }
 }
 else
 {
  Count=0;
  Data =NULL;
 }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>        ::                   ~TArray                           (                                                    )
{
 TBase *p;
 if (Data!=NULL)
 {
  for (p=Data+Count-1; p>=Data; --p)
  {
   p->~TBase();
  }
  free(Data);
 }
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    ReSize                           (size_t                            Count             )
{
 TBase  *Buffer;
 TBase  *p;
 TBase  *End;
 size_t  NewCount;
 size_t  NewSize;
 NewSize=Count*sizeof(TBase);
 if ((NewSize/sizeof(TBase))==Count)
 {
  if (Count>this->Count)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    NewCount=_msize(Buffer)/sizeof(TBase);
    for (p=Buffer+NewCount-1, End=Buffer+this->Count; p>=End; --p)
    {
     new (p) TBase;
    }
    this->Count=NewCount;
          Data =Buffer;
   }
  }
  if (Count<this->Count)
  {
   if (Count>0)
   {
    for (p=Data+this->Count-1, End=Data+Count; p>=End; --p)
    {
     p->~TBase();
    }
    Buffer=(TBase*)realloc((void*)Data, NewSize);
    NewCount=_msize(Buffer)/sizeof(TBase);
    this->Count=NewCount;
          Data =Buffer;
   }
   else
   {
    for (p=Data+Count-1; p>=Data; --p)
    {
     p->~TBase();
    }
    free(Data);
    this->Count=0;
          Data =NULL;
   }
  }
 }
 return Count==this->Count;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    Empty                            (                                                    )
{
 return (Count==0);
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    Filled                           (                                                    )
{
 return (Count!=0);
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>        ::                    operator size_t                  (                                                    )
{
 return Count;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TBase                                      &
TArray <TBase>        ::                    operator []                      (size_t                            Index             )
{
 return *(Data+Index);
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>                             &
TArray <TBase>        ::                    operator =                       (const
                                                                              TArray                           &Original          )
{
 TBase  *Buffer;
 TBase  *Source;
 TBase  *Target;
 TBase  *p;
 TBase  *End;
 size_t  NewCount;
 size_t  NewSize;
 NewSize=Original.Count*sizeof(TBase);
 if (Original.Count>Count)
 {
  Buffer=(TBase*)realloc((void*)Data, NewSize);
  if (Buffer!=NULL)
  {
   NewCount=_msize(Buffer)/sizeof(TBase);
   for (p=Buffer+NewCount-1, End=Buffer+this->Count; p>=End; --p)
   {
    new (p) TBase;
   }
   for (Target=Buffer+NewCount-1, Source=Original.Data+NewCount-1; Target>=Buffer; --Target, --Source)
   {
    *Target=*Source;
   }
   this->Count=NewCount;
         Data =Buffer;
  }
  else
  {
   if (Data!=NULL)
   {
    for (Target=Buffer+Count-1, Source=Original.Data+Count-1; Target>=Buffer; --Target, --Source)
    {
     *Target=*Source;
    }
   }
  }
  return *this;
 }
 if (Original.Count>0)
 {
  if (Original.Count<Count)
  {
   for (p=Data+this->Count-1, End=Data+Original.Count; p>=End; --p)
   {
    p->~TBase();
   }
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   for (Target=Buffer+Count-1, Source=Original.Data+Count-1; Target>=Buffer; --Target, --Source)
   {
    *Target=*Source;
   }
   this->Count=Count;
         Data =Buffer;
   return *this;
  }
  if (Original.Count==Count)
  {
   for (Target=Data+Count-1, Source=Original.Data+Count-1; Target>=Data; --Target, --Source)
   {
    *Target=*Source;
   }
   return *this;
  }
 }
 if (Original.Count==0)
 {
  if (Data!=NULL)
  {
   for (p=Data+this->Count-1; p>=Data; --p)
   {
    p->~TBase();
   }
   free(Data);
   this->Count=0;
         Data =NULL;
  }
  return *this;
 }
 return *this;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    Addition                         (const
                                                                              TBase                            &s                 )
{
 TBase  *Buffer;
 size_t  NewSize;
 size_t  NewCount;
 NewCount=Count+1;
 if (NewCount>0)
 {
  NewSize=NewCount*sizeof(TBase);
  if (((NewSize)/sizeof(TBase))==NewCount)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    if (_msize(Buffer)==NewSize)
    {
     new (Buffer+Count) TBase(s);
     Count=NewCount;
     Data =Buffer;
     return true;
    }
   }
  }
 }
 return false;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    Addition                         (                                                    )
{
 TBase  *Buffer;
 size_t  NewSize;
 size_t  NewCount;
 NewCount=Count+1;
 if (NewCount>0)
 {
  NewSize=NewCount*sizeof(TBase);
  if (((NewSize)/sizeof(TBase))==NewCount)
  {
   Buffer=(TBase*)realloc((void*)Data, NewSize);
   if (Buffer!=NULL)
   {
    if (_msize(Buffer)==NewSize)
    {
     new (Buffer+Count) TBase;
     Count=NewCount;
     Data =Buffer;
     return true;
    }
   }
  }
 }
 return false;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TBase                                      &
TArray <TBase>        ::                    Last                             (                                                    )
{
 return *(Data+Count-1);
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
TArray <TBase>
TArray <TBase>        ::                    SubArray                         (size_t                            Start             ,
                                                                              size_t                            End               )
{
 TArray <TBase>  Result;
 TBase          *Source;
 TBase          *Target;
 TBase          *Stop;
 Result.ReSize(End-Start+1);
 for (Source=Data+End, Target=Result.Data+End-Start, Stop=Data+Start; Source>=Stop; --Source, --Target)
 {
  *Target=*Source;
 }
 return Result;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    operator ==                      (const
                                                                              TArray                           &Compare           )
{
 TBase *Left;
 TBase *Right;
 if (Count==0)
 {
  return ((Compare.Count)==0);
 }
 if (Count!=Compare.Count)
 {
  return false;
 }
 for (Left=Data+Count-1, Right=Compare.Data+Count-1; Left>=Data; --Left, --Right)
 {
  if ((*Left)!=(*Right))
  {
   return false;
  }
 }
 return true;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
bool
TArray <TBase>        ::                    operator !=                      (const
                                                                              TArray                           &Compare           )
{
 TBase *Left;
 TBase *Right;
 if (Count==0)
 {
  return ((Compare.Count)!=0);
 }
 if (Count!=Compare.Count)
 {
  return true;
 }
 for (Left=Data+Count-1, Right=Compare.Data+Count-1; Left>=Data; --Left, --Right)
 {
  if ((*Left)!=(*Right))
  {
   return true;
  }
 }
 return false;
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename TBase>
size_t
TArray <TBase>        ::                    Find                             (const
                                                                              TBase                            &s                 )
{
 TBase *p;
 for (p=Data+Count-1; p>=Data; --p)
 {
  if ((*p)==s)
  {
   return (p-Data);
  }
 }
 return std::numeric_limits<size_t>::max();
}
//=====================================================================================================================================================================================================
#endif // TARRAY_HPP_INCLUDED
. Пройти в том же ReSize после realloc по всем элементам и для каждого отдельно выполнить
C++
1
Data[i].a.parent=&(Data[i]);
не проблема, да вот беда, придётся на parent вешать public и тогда можно выполнить даже в main что нибудь вроде
C++
1
Array[2].a.parent=&(Array[34].a);
.
0
Заблокирован
15.03.2014, 11:29
taras atavin, "код целиком" - это не тоже самое, что кучу лишнего кода (который вообще не в тему, кстати).
Это значит, что я жду пример, который будет компилироваться
Пройти в том же ReSize после realloc по всем элементам и для каждого отдельно выполнить
не проблема, да вот беда, придётся на parent вешать public и тогда можно выполнить даже в main что нибудь вроде
В твоем коде вообще нет main. Я не хочу гадать что ты там делаешь не так.
Именно такой пример, в котором у тебя "адрес портится".

Цитата Сообщение от taras atavin Посмотреть сообщение
И похоже не имеет на c++ качественного решения, которое бы не страдало возможностью порчи адреса агрегирующего объекта: можно завести член

Цитата Сообщение от taras atavin Посмотреть сообщение
а тогда к нему будет доступ откуда угодно и можно будет его модифицировать без какой либо связи с перемещением агрегирующего объекта.
Вот эту проблему должен код отражать, а не другую. Потому что я тебя вообще не понимаю. Что такое "перемещение агрегирующего объекта"? Я вообще перемещение объекта не совсем представляю. ты имеешь ввиду это: http://en.cppreference.com/w/c... onstructor ? -почему в коде этого нет?
Формулируй мысли нормально с общепринятой терминологией, иначе никто не ответит.
0
 Аватар для taras atavin
4226 / 1799 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
15.03.2014, 11:37  [ТС]
Цитата Сообщение от rrrFer Посмотреть сообщение
почему в коде этого нет?
realloc в коде есть, а он может вернуть новый адрес.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.03.2014, 11:37

Может ли функция иметь аргументом другую функцию или объект?
Внимание тупой вопрос )) А может ли функция иметь аргументом другую функцию или объект?

Реализовать двухсвязный список. Каждый элемент списка может содержать один объект
Здравствуйте, мне нужно было реализовать двухсвязный список. Каждый элемент списка может содержать один объект. Объект может быть трех...

Как достать объект-контейнер, а не его элемент
Добрый вечер всем. Возник вопрос. Я читал Страуструпа и на одной из его глав, есть упражнение по созданию класса-контейнера, в...

при вызове конструктора присваивания надо возвращать ссыль на объект или сам объект. Смысл? Значения нужных полей меняютмся и без этого!
Друзья! Обнаружил пробел в знаниях. Собсно, вопрос в теме. Дополню лишь: поля объекта меняются на нужные значения и безо всякого возврата...

Объект osteram& или как его вывести в переменную ?
Здравствуйте Объект osteram&amp; или как его вывести в переменную ? cin... cout... printf... scanf А вот как же вывети поток...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru