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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
14.03.2014, 09:27     Может ли объект-член, или объект-элемент достучаться к содержащему его? #1
Предположим,
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ом.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.03.2014, 09:27     Может ли объект-член, или объект-элемент достучаться к содержащему его?
Посмотрите здесь:

C++ [C++]Один объект не может дополнить другой.
при вызове конструктора присваивания надо возвращать ссыль на объект или сам объект. Смысл? Значения нужных полей меняютмся и без этого! C++
Объект osteram& или как его вывести в переменную ? C++
Реализовать двухсвязный список. Каждый элемент списка может содержать один объект C++
интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
14.03.2014, 17:34  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #21
Цитата Сообщение от Alex5 Посмотреть сообщение
B A::* q; // указатель на член класса ( член, имеющий тип B )
* * q = &A::b1; // *0x00000008
Это что за синтаксис такой?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,629
14.03.2014, 17:43     Может ли объект-член, или объект-элемент достучаться к содержащему его? #22
taras atavin, обычный для указателей на члены класса. Это по сути как раз те самые смещения. Поэтому их получают через определение класса
&A::b1
, не через объект.
А вот reinterpret_cast в этом случае - нехорошо. Пример не учитывает выравнивание, к тому же компилятор для не standard-layout классов может менять местами поля в целях оптимизации. Ну и достаточно просто добавить в такой класс еще одно поле и не провести соответствующих изменений в коде доступа к полям, то все смещения "поплывут".
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
14.03.2014, 17:45  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #23
Цитата Сообщение от DrOffset Посмотреть сообщение
taras atavin, обычный для указателей на члены класса. Это по сути как раз те самые смещения. Поэтому их получают через определение класса
&A::b1
, не через объект.
Расшифруй как для нуба в кубе.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,629
14.03.2014, 18:04     Может ли объект-член, или объект-элемент достучаться к содержащему его? #24
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);
Для указатель на методы те же правила. Только в отличие от данных, нельзя получить абсолютный адрес метода, только вот такой относительный.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
14.03.2014, 18:07  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #25
Нда. А кто мешает юзать имена полей и поручить смещения компилятору?
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,629
14.03.2014, 18:14     Может ли объект-член, или объект-элемент достучаться к содержащему его? #26
taras atavin, никто. Просто иногда это бывает полезно.

Добавлено через 6 минут
Лично я не находил применения таким указателям на данные. Но зато использовал указатели на методы (у них синтаксис похож, только параметры еще добавляются). Это полезно при реализации делегатов.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
14.03.2014, 18:23  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #27
Цитата Сообщение от 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;
 
    // ... 
}
? А ведь по условию функцией может владеть даже элемент динамического массива.
Alex5
883 / 618 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
14.03.2014, 20:18     Может ли объект-член, или объект-элемент достучаться к содержащему его? #28
Цитата Сообщение от 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 возникнет ошибка.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,629
14.03.2014, 23:29     Может ли объект-член, или объект-элемент достучаться к содержащему его? #29
Цитата Сообщение от Alex5 Посмотреть сообщение
Данный пример как раз учитывает выравнивание.
В принципе было бы достаточно этой фразы. Действительно, учитывает. А "магическая" константа была в комментарии, а не в коде, на что я и не обратил внимания
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 07:37  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #30
Данный пример не учитывает, что однотипных членов может быть несколько.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 07:48  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #31
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;
}
Миниатюры
Может ли объект-член, или объект-элемент достучаться к содержащему его?  
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 07:49  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #32
На скрине видно, что функция не знает, для какого именно члена вызвана на самом деле и не может определить адрес искомого объекта.
rrrFer
Заблокирован
15.03.2014, 07:54     Может ли объект-член, или объект-элемент достучаться к содержащему его? #33
Цитата Сообщение от taras atavin Посмотреть сообщение
Данный пример не учитывает, что однотипных членов может быть несколько.
расскажи нам как это?
Может ли объект-член, или объект-элемент достучаться к содержащему его?
может, если ты поместишь в него нужный указатель .
Иначе никак не может
DrOffset,
Что там о виртуальных функциях в твоих примерах?
Откуда дочерний объект уверен, что он является полем класса "А"? - в твоих примерах именно так. Т.е. поместить его в другой класс я не могу.
Унылый вариант.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 07:57  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #34
А ведь есть ещё такие пакости:
1. Класс A является типом членов одновременно нескольких других классов.
2. Класс A является типом элементов реализованных на указателях динамических массивов и индекс элемента членам самого класса A не известен.
3. Экземпляр A может быть и обычным объектом, а не частью другого объекта.

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

А по теме, я уже сказал. Помещай в дочерний класс указатель на родительский. Только так.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 08:07  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #36
Цитата Сообщение от rrrFer Посмотреть сообщение
Да ты в код то посмотри:
Код C++
1
q = &B::a1;
Я то как раз сразу это разглядел, а некоторым объяснять приходится, причём, на скринах.

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

Добавлено через 5 минут
И похоже не имеет на c++ качественного решения, которое бы не страдало возможностью порчи адреса агрегирующего объекта: можно завести член
C++
1
void *parent;
, но его придётся исправлять при каждом перемещении агрегирующего объекта, для чего придётся этот член открыть в public, а тогда к нему будет доступ откуда угодно и можно будет его модифицировать без какой либо связи с перемещением агрегирующего объекта. Здесь нужны встроенные языковые средства, а parent должен модифицироваться только неявно.
rrrFer
Заблокирован
15.03.2014, 08:13     Может ли объект-член, или объект-элемент достучаться к содержащему его? #37
И похоже не имеет на c++ качественного решения, которое бы не страдало возможностью порчи адреса агрегирующего объекта: можно завести член
Чето я не понял кто там тебе адрес портит (или может испортить). Приведи пример (код целиком, а не кусками, мне лень дописывать)..
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 10:02  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #38
Цитата Сообщение от 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);
.
rrrFer
Заблокирован
15.03.2014, 11:29     Может ли объект-член, или объект-элемент достучаться к содержащему его? #39
taras atavin, "код целиком" - это не тоже самое, что кучу лишнего кода (который вообще не в тему, кстати).
Это значит, что я жду пример, который будет компилироваться
Пройти в том же ReSize после realloc по всем элементам и для каждого отдельно выполнить
не проблема, да вот беда, придётся на parent вешать public и тогда можно выполнить даже в main что нибудь вроде
В твоем коде вообще нет main. Я не хочу гадать что ты там делаешь не так.
Именно такой пример, в котором у тебя "адрес портится".

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

Цитата Сообщение от taras atavin Посмотреть сообщение
а тогда к нему будет доступ откуда угодно и можно будет его модифицировать без какой либо связи с перемещением агрегирующего объекта.
Вот эту проблему должен код отражать, а не другую. Потому что я тебя вообще не понимаю. Что такое "перемещение агрегирующего объекта"? Я вообще перемещение объекта не совсем представляю. ты имеешь ввиду это: http://en.cppreference.com/w/cpp/lan...ve_constructor ? -почему в коде этого нет?
Формулируй мысли нормально с общепринятой терминологией, иначе никто не ответит.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2014, 11:37     Может ли объект-член, или объект-элемент достучаться к содержащему его?
Еще ссылки по теме:

компилятор считает объект l-value, но объект таковым не является C++
C++ Как достать объект-контейнер, а не его элемент
Если объект константный, означает ли это, что ни один его член-элемент или член-метод не изменится? C++

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.03.2014, 11:37  [ТС]     Может ли объект-член, или объект-элемент достучаться к содержащему его? #40
Цитата Сообщение от rrrFer Посмотреть сообщение
почему в коде этого нет?
realloc в коде есть, а он может вернуть новый адрес.
Yandex
Объявления
15.03.2014, 11:37     Может ли объект-член, или объект-элемент достучаться к содержащему его?
Ответ Создать тему
Опции темы

Текущее время: 21:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru