【急募】オブジェクト指向のプログラミングに強い人来てくれ!!




1: 名無しの民 2019/05/10(金) 21:12:25.506 ID:hiXRyAIv0
遺伝的に完全なデータ渡しをしたいんだけど方法ある?
例えば
public class A {
int id;
public B b;
publin static void DeleteB(A a){
a.b = null;
}
}
っていうクラスがあったとして
A a = new A();
a.b = new B();
A.DeleteB(a);
っていう処理をするとデータ渡しなのにAのメンバbが参照型のせいでnewしたaのメンバbがnullになってしまうよね
こうならないように渡したデータのクラスが持つ参照型のメンバに関しても参照先は異なるけど参照先のデータは同じ、みたいなことが遺伝的に成り立つようにしたい
つまり元のオブジェクトとは干渉しない完全なクローンデータを渡したいんだが可能?

9: 名無しの民 2019/05/10(金) 21:38:01.980 ID:hiXRyAIv0
>>6
今自分が取り組んでるプロジェクトにMVPのデザインパターンを取り入れてるんだがPresenterからViewのメソッドを呼ぶときに
Modelのデータを渡したいんだが>>1にあるような理由でModelのインスタンスのメンバを書き換えられるようになってしまうから保守性を高める意味でちょっと訊いてみたかった
コンストラクタでやるのも頑張れば可能かもしれないが参照型のメンバがさらに参照型のメンバを持ってたりすると大変

43: 名無しの民 2019/05/10(金) 23:03:32.692 ID:bnodbkNS0
>>41
>>9
>>1の書いてるのはC#

26: 名無しの民 2019/05/10(金) 22:16:36.353 ID:iOwtAuty0
>>1
なんでstaticにすんの?

28: 名無しの民 2019/05/10(金) 22:20:21.785 ID:hiXRyAIv0
>>26
A型の値渡しの一例を挙げたかっただけ
staticであることは全く本質ではない

53: 名無しの民 2019/05/10(金) 23:13:27.969 ID:DErLLtx10
>>52
それが問題があって
C++の場合上に書いているクラスは下のクラスを呼び出したり色々入れたりも出来るけど
下に書いたクラスを上のクラスに同じようにできないんだわ
おそらくC#も同じ仕様かと
Javaはこれが出来るんだ
コンパイルする時なのか知らんけど
Javaの場合一度すべてのクラスを使える状態にしてからやる感じになるらしい
>>1の悩みはとてもいい悩みだよ
真面目にアプリ作り始めると誰しも1回はぶち当たる壁だと思う
俺もこれで悩んで10日くらいゲーム作りとまった

56: 名無しの民 2019/05/10(金) 23:16:18.538 ID:iOwtAuty0
>>53
それC#は違うよ
プロトタイプが必要ないから同じファイル内で下が見れないとかにはならない
ファイル分けしたら循環参照とかになるかもしれないけどそういう場合はinterfaceで切り分けたりとか手段はある

58: 名無しの民 2019/05/10(金) 23:17:18.062 ID:DErLLtx10
>>56
でもたぶんそのクラス設計は間違ってる

64: 名無しの民 2019/05/10(金) 23:25:46.431 ID:iOwtAuty0
>>58
まぁ大体相互参照が必要な場合ってそのクラス自体をメンバに持たせるんじゃなく親クラスかI/Fを持たせるもんじゃない?

66: 名無しの民 2019/05/10(金) 23:36:22.000 ID:DErLLtx10
>>64
うーん・・・
俺素人プログラマだから何とも言えないけど
まず一つ一番デカイクラスを作る
俺の中だと空間クラスとよんでる
それともう一つデータクラスが必要になって
その空間クラスとデータクラスが色んなクラスを行ったり来たりするイメージ

59: 名無しの民 2019/05/10(金) 23:17:27.208 ID:bnodbkNS0
>>53
低レイヤー詳しくないけどJVMに訳す時に首尾よくリンクするってことなのかね。
だとするとC#も.Netに訳す時にうまくやってくれる期待ができるかな?

60: 名無しの民 2019/05/10(金) 23:20:36.980 ID:DErLLtx10
>>59
たぶんJavaとCはコンパイルというかそもそもが違う気がする
Cってのは上から順番に展開していく感じなんだけど
Javaってのは全部展開してから動く感じ
で、高速なのはCなんだけど
Javaの場合>>1のやろうとしてることは簡単に出来る

2: 名無しの民 2019/05/10(金) 21:18:36.569 ID:i28ptRekH
可能

3: 名無しの民 2019/05/10(金) 21:19:52.434 ID:hiXRyAIv0
>>2
お?

4: 名無しの民 2019/05/10(金) 21:21:52.119 ID:bnodbkNS0
JavaやめてKotlin使う

5: 名無しの民 2019/05/10(金) 21:25:53.669 ID:hiXRyAIv0
>>4
KotlinはJavaのデータ渡しとは違うのか?

7: 名無しの民 2019/05/10(金) 21:30:09.009 ID:bnodbkNS0
>>5
関数型言語っぽく書けるけどJVMで動くステキな奴。

10: 名無しの民 2019/05/10(金) 21:40:07.553 ID:hiXRyAIv0
>>7
なるほど
Javaの上位互換とは訊くが触ったことないんだよな…
そろそろAndroidStudio勉強しようかなと思ってるがKotlinの方がいいのかな
Javaは最近触れてないけど一時期よく使ってた

16: 名無しの民 2019/05/10(金) 21:57:48.489 ID:bnodbkNS0
>>10
てっきりガッコの課題かと思って茶化したがプロジェクトやってんのね。ごめん。
言語何?データ渡しってのはいわゆる値渡しのことだよね?

18: 名無しの民 2019/05/10(金) 22:01:07.585 ID:hiXRyAIv0
>>16
言語はC#
そうそう値渡しのことです

6: 名無しの民 2019/05/10(金) 21:29:12.499 ID:1yZqwlpOr
んー頭のいいことしてるね
コンストラクタじゃ駄目なん

8: 名無しの民 2019/05/10(金) 21:36:06.232 ID:1yZqwlpOr
ああ言ってる意味よく分かってなかったんだけど
A a = new A();
a.b = new B();

A.DeleteB(a);
↑こいつが問題ってことね
Aだから悪いのであってa.DeleteB(a)だったらいいんじゃないの?

A.DeleteB(a)のままで使うとしたらどうしたら良いんだろね…
クラスAでBを初期化しとかざるを得ない気がすんだけど…

11: 名無しの民 2019/05/10(金) 21:41:59.056 ID:hiXRyAIv0
>>8
A.DeleteB(a)でもa.DeleteB(a)でも変わらなくね?
そっちじゃなくてデータ渡しの仕組みの問題

12: 名無しの民 2019/05/10(金) 21:43:01.818 ID:1yZqwlpOr
>>11
あっメソッドの中身A.bに空目してたよ

13: 名無しの民 2019/05/10(金) 21:48:44.218 ID:1yZqwlpOr
んーぼくjava初学者だからよく分かんないんだけど要はDeleteBのアクセス制御が出来りゃいいの…?
a.b=nullでデータが書き換えられる事がリスクってことでええのんよね…?
参照先は異なるけどーからの一文がよくわかんない…

15: 名無しの民 2019/05/10(金) 21:53:53.513 ID:hiXRyAIv0
>>13
アクセス制御の話ではなく渡されたデータの参照型のメンバ変数に格納されたアドレスを元のインスタンスのそれとは異なるようにしたい
でも参照先のデータは同じになるようにしたい
メモリ管理の話なので初学者だとちょっと高度かもしれない

14: 名無しの民 2019/05/10(金) 21:49:12.725 ID:1yZqwlpOr
なんか上手いやり方出来たらおせーてね…

17: 名無しの民 2019/05/10(金) 21:58:47.889 ID:1yZqwlpOr
それつまりcloneメソッドみたいなの作ればいいんじゃないの…?
多分あるよ…
object型にはcloneメソッドがあるからそれ実装すりゃいいんじゃないかな…

19: 名無しの民 2019/05/10(金) 22:02:44.592 ID:hiXRyAIv0
>>17
cloneって参照型もちゃんと複製してくれるんだっけ

21: 名無しの民 2019/05/10(金) 22:09:03.540 ID:1yZqwlpOr
>>19
参照型のメンバが参照型だったら参照のコピーになっちゃうかも…
でももしそうだとしたらゴミメソッドすぎるよね
apiマニュアル読むのめんどくさいから読んできて…
やったことないんだけどたとえばAクラスがメンバとして何を持ってるかって調べる方法あんのかな…?

25: 名無しの民 2019/05/10(金) 22:16:25.668 ID:hiXRyAIv0
>>21
確かjavascriptはすべてのメンバを走査できたような記憶があるがコンパイル言語は無さそう…いや、分からんけど
まあ浅いコピーだと中途半端だよねやっぱり

20: 名無しの民 2019/05/10(金) 22:05:07.718 ID:bnodbkNS0

22: 名無しの民 2019/05/10(金) 22:11:56.132 ID:hiXRyAIv0
>>20
うーむ…DeepCopyは自作するしかないのか

39: 名無しの民 2019/05/10(金) 22:54:21.959 ID:bnodbkNS0

23: 名無しの民 2019/05/10(金) 22:12:37.362 ID:bnodbkNS0
MVPの願望をちょっと理解してくる

24: 名無しの民 2019/05/10(金) 22:14:30.353 ID:HcLCgw1JM
インターフェースで定義と初期化して
後で継承すれば

27: 名無しの民 2019/05/10(金) 22:18:52.094 ID:hiXRyAIv0
>>24
それでいけるかね…
多分関連する全てのクラスに対してそれやらないといけなくなるだろうから面倒というかもっと上手いやり方は無いものかね

34: 名無しの民 2019/05/10(金) 22:32:27.287 ID:HcLCgw1JM
>>27
そもそもそんなコード必要ないようにかけば
C言語だと悩まないわけで

29: 名無しの民 2019/05/10(金) 22:20:39.950 ID:mBz7HEb20
Serializableてのがあるらしいが

31: 名無しの民 2019/05/10(金) 22:23:25.706 ID:hiXRyAIv0
>>29
それはI/Oとかじゃないの
普通にメソッドに渡すだけなのにシリアライズとかするか?

40: 名無しの民 2019/05/10(金) 22:57:37.009 ID:mBz7HEb20
>>31
しないね
DeepCopyが面倒なら試してみればという程度の意味です

30: 名無しの民 2019/05/10(金) 22:20:56.354 ID:iOwtAuty0
まずBにcloneっていうメソッドの定義が必要だし
こういう件だと全てに置いてstaticは必要ない

32: 名無しの民 2019/05/10(金) 22:27:04.494 ID:eNLoag8H0
×遺伝的
〇推移的

33: 名無しの民 2019/05/10(金) 22:31:22.544 ID:iOwtAuty0
まずideoneでやってみろ
https://www.ideone.com/

36: 名無しの民 2019/05/10(金) 22:38:48.239 ID:wuXjw/tx0
cloneメソッドを作れ、で終わる話では?

37: 名無しの民 2019/05/10(金) 22:45:13.849 ID:sxCXS0rj0
> こうならないように渡したデータのクラスが持つ参照型のメンバに関しても参照先は異なるけど参照先のデータは同じ、みたいなことが遺伝的に成り立つようにしたい

これがさっぱり意味がわからないんだけどw
ぐちゃぐちゃの日本語にしか見えない
「こうしたい」って一言で言えない?

38: 名無しの民 2019/05/10(金) 22:52:04.315 ID:iOwtAuty0
そもそも
A a = new A();
a.b = new B();
じゃなく
A a = new A();
B b = new B();
a.b = b;
って書けば済む話じゃない?

41: 名無しの民 2019/05/10(金) 23:00:59.734 ID:DErLLtx10
これjavaなら出来るんだけど
C++だと出来ないのよね
というかそもそもクラス設計に問題がある
ゲーム作ってた時に初めてぶち当たった壁だわ
自動車のタイヤとかエンジンみたいな感覚だとゲーム作れない
設計が間違ってる
ゲームだと一番外側に座標という空間クラスを作るって所までは理解したけど
何を作りたいのかわからないから何とも言えない

42: 名無しの民 2019/05/10(金) 23:01:19.139 ID:HcLCgw1JM
1さんの件はよくわからないがJavaとかC++は複雑な機能使いすぎて返って悩むってことよくある
Pythonでは悩んだことあんまないのでオブジェクト指向というよりは単に言語仕様の罠な気がする

44: 名無しの民 2019/05/10(金) 23:03:37.931 ID:HcLCgw1JM
C++はみんな糞っていうよね
理由はいろいろあるけども
最近は案件も減った
Goのほうがいいみたい

45: 名無しの民 2019/05/10(金) 23:03:41.419 ID:u0ipE5lM0
C#で簡単にディープコピーする方法ありませんかって聞けばよいのに
こんな分かりにくい例を出すな

一番簡単そうなのはこれだけど
https://www.atmarkit.co.jp/ait/articles/1705/24/news040.html

46: 名無しの民 2019/05/10(金) 23:03:47.742 ID:DErLLtx10
いやこれ誰しも悩むとこよたぶん
何か作ろうとし始めたら必ずこの壁にぶつかるはず

47: 名無しの民 2019/05/10(金) 23:03:49.295 ID:enYrHJs4d
C++ならコピーコンストラクタ作れよ

48: 名無しの民 2019/05/10(金) 23:05:58.653 ID:iOwtAuty0
> publin static void DeleteB(A a){
> a.b = null;
> }
>データ渡しなのにAのメンバbが参照型のせいでnewしたaのメンバbがnullになってしまう

どうなって欲しいのかイマイチ分からんね

51: 名無しの民 2019/05/10(金) 23:08:13.503 ID:iATIg5rja
>>48
aのメンバbをnullにする処理をしてるんだからnullにならない方が意味分からん

49: 名無しの民 2019/05/10(金) 23:06:21.967 ID:mBz7HEb20
循環参照があるオブジェクトのDeepCopyとかよく考えないで作ると面白いことになりそう

50: 名無しの民 2019/05/10(金) 23:07:07.331 ID:DErLLtx10
C++だと上に書いたクラスに下のクラスを入れるのは出来るけど
その逆が出来ないんだよ
そのようなクラスはありません的なエラーになる
おそらくC#も同じじゃないかな
Javaの場合これが出来るんだな
でもおそらくこれが出てきてしまう設計にまず問題がある
クラスを理解していない可能性が高い

52: 名無しの民 2019/05/10(金) 23:10:34.136 ID:iOwtAuty0
>>50
classのメンバ関数以外の定義ってヘッダーに書くもんじゃなかったっけ?
あとメンバ関数のプロトタイプもヘッダーに書くから基本的に定義不明で参照できない事にはならないはずだけど

54: 名無しの民 2019/05/10(金) 23:14:45.017 ID:DErLLtx10
で、結論がクラス設計が間違ってる
まず大きなクラスを一つ作り
その中でクラスを生み出していくのが正解だから
A→BはあるけどB→Aはあり得ないんだわ

55: 名無しの民 2019/05/10(金) 23:15:58.469 ID:DErLLtx10
つまりAの中でBやCを作る
またAの中でBの子供のDやCを量産して使ったりするわけよ
不可逆なんよ
BからAにはしない
おそらくこれがオブジェクト指向なんだと思う
違ってたら突っ込みはいくらでもして素人プログラマーに毛が生えた程度だから

62: 名無しの民 2019/05/10(金) 23:23:31.692 ID:qhuku/b00
例がよくわからんけど、public メンバーな時点でカプセル化破壊してるから、オブジェクト指向云々で話をするのかきついんじゃないかな

67: 名無しの民 2019/05/11(土) 00:17:18.310 ID:yl3O/DAb0
それはオブジェクト指向プログラミングじゃなくて手続き型プログラミングのやり方だよね

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

【中古】オブジェクト指向でなぜつくるのか / 平沢章
価格:680円(税込、送料別) (2020/5/17時点)


引用元

https://hebi.5ch.net/test/read.cgi/news4vip/1557490345/




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です