回答編集履歴

1

親のポインタ

2017/01/26 18:37

投稿

raccy
raccy

スコア21735

test CHANGED
@@ -259,3 +259,225 @@
259
259
 
260
260
 
261
261
  私個人の意見ですが、オブジェクトの共有目的で参照を使った場合、寿命の管理が難しくなり、また、混乱しやすいと思っています。むしろ、オブジェクトの寿命について意識しなければならないポインタを使った方がまだいいと思っています。私が書く時は、値渡しだとパフォーマンスが低下することを防ぐ目的以外では基本的に参照を使いません。
262
+
263
+
264
+
265
+ ---
266
+
267
+
268
+
269
+ 【追記】
270
+
271
+
272
+
273
+ アイデアの一つですが、親子関係を強調するなら、親のポインタを持たせるという手もあります。(コードは割と適当なので参考程度に)
274
+
275
+
276
+
277
+ ```C++
278
+
279
+ #include <iostream>
280
+
281
+ #include <memory>
282
+
283
+
284
+
285
+ class Data;
286
+
287
+ class A;
288
+
289
+ class B;
290
+
291
+ class C;
292
+
293
+
294
+
295
+ class Data
296
+
297
+ {
298
+
299
+ private:
300
+
301
+ int val;
302
+
303
+
304
+
305
+ public:
306
+
307
+ Data(int val = 0) : val(val){};
308
+
309
+ void addData(int x)
310
+
311
+ {
312
+
313
+ this->val += x;
314
+
315
+ }
316
+
317
+ int getVal()
318
+
319
+ {
320
+
321
+ return this->val;
322
+
323
+ }
324
+
325
+ };
326
+
327
+
328
+
329
+ class A
330
+
331
+ {
332
+
333
+ friend B;
334
+
335
+ friend C;
336
+
337
+
338
+
339
+ private:
340
+
341
+ Data _data;
342
+
343
+ std::unique_ptr<B> _objectB;
344
+
345
+
346
+
347
+ public:
348
+
349
+ A(int val = 0) : _data(val), _objectB(std::make_unique<B>(this))
350
+
351
+ {
352
+
353
+ }
354
+
355
+ Data &getData()
356
+
357
+ {
358
+
359
+ return this->_data;
360
+
361
+ }
362
+
363
+ B *getB()
364
+
365
+ {
366
+
367
+ return this->_objectB.get();
368
+
369
+ }
370
+
371
+ void addData(int x)
372
+
373
+ {
374
+
375
+ this->_data.addData(x);
376
+
377
+ }
378
+
379
+ };
380
+
381
+
382
+
383
+ class B
384
+
385
+ {
386
+
387
+ friend C;
388
+
389
+
390
+
391
+ private:
392
+
393
+ A *const parent;
394
+
395
+ std::unique_ptr<C> _objectC;
396
+
397
+
398
+
399
+ public:
400
+
401
+ B(A *parent) : parent(parent), _objectC(std::make_unique<C>(this))
402
+
403
+ {
404
+
405
+ }
406
+
407
+ C *getC()
408
+
409
+ {
410
+
411
+ return this->_objectC.get();
412
+
413
+ }
414
+
415
+ Data &getData()
416
+
417
+ {
418
+
419
+ return this->parent->_data;
420
+
421
+ }
422
+
423
+ };
424
+
425
+
426
+
427
+ class C
428
+
429
+ {
430
+
431
+ private:
432
+
433
+ B *const parent;
434
+
435
+
436
+
437
+ public:
438
+
439
+ C(B *parent) : parent(parent)
440
+
441
+ {
442
+
443
+ }
444
+
445
+ Data &getData()
446
+
447
+ {
448
+
449
+ return this->parent->parent->_data;
450
+
451
+ }
452
+
453
+ };
454
+
455
+
456
+
457
+ int main()
458
+
459
+ {
460
+
461
+ auto a = std::make_unique<A>(0);
462
+
463
+ a->addData(2);
464
+
465
+ std::cout << "a _data: " << a->getData().getVal() << std::endl;
466
+
467
+ std::cout << "a _objectB _data: " << a->getB()->getData().getVal()
468
+
469
+ << std::endl;
470
+
471
+ std::cout << "a _objectB _objectC _data: "
472
+
473
+ << a->getB()->getC()->getData().getVal() << std::endl;
474
+
475
+ return 0;
476
+
477
+ }
478
+
479
+ ```
480
+
481
+
482
+
483
+ 親で共有させたいメンバーが増えていってもそれぞれの子でメンバーも宣言をする必要も無いですし、子が持つメンバーも親一人のポインタだけで済みます。ただ、親のコンストラクタでしか子が作れないので、ポインタにしないと駄目だったはず…。オブジェクト間で親子関係を持たせられるQtがそんな作りだったと思いました(Qtは自前で参照カウントとかしていたはずなので、もうちょっと複雑ですが)。