- ベストアンサー
C++メンバ変数をポインタで宣言するデメリット
- クラスAが、クラスXと、クラスYを持っているとき、メンバであるクラスX、クラスYをポインタで宣言すると、可読性が悪くなる。
- ポインタで宣言すると、実際にはどの型のクラスが格納されているかがわからず、追いかけるのが難しくなる。
- ポインタではなくクラスX/クラスYの型として宣言することで、可読性を向上させることができる。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>『どの型の値がそこに突っ込まれているかは、代入されているところを探して確認しないとわからない。』 本当は、これがデメリットに思えるようなら、そもそもクラスの設計が良くない(オブジェクト指向的になってない)ってことな気もしますが。。 RTTIとか有効にすれば、とりあえず、どの型が突っ込まれているかは分かるようになるのでは。
その他の回答 (1)
- hanabutako
- ベストアンサー率54% (492/895)
> 私は、処理を確認する際、『どの型の値がそこに突っ込まれているかは、代入されているところを探して確認しないとわからない。』というのが、可読性は悪いわ、確認に時間が取られるわで、非常に大きなデメリットと考えています。 なんかデザインがダメな感じがします。 Liskov substitution principleに従ってないsubclassを作ってませんか? actual typeを逐一確認しないとコードが書けないとしたら、subclassなんて使わないほうがいいです。ほぼ確実に、間違った継承の使い方をしています。 #1さんのおっしゃるとおり、typeidでactual typeを知ることは可能ですが、そんなことをするよりもデザインの再考をしたほうが良いかと。 個人的には、 http://okwave.jp/qa/q8189254.html のように Liskov substitution principle に反するようなコーディングが必須の例というのはあまり良くないと思うのですが。それよりも例えばユーティリティ的なモジュールを作ったほうが良くないですか。あるいは、2つのクラスとも単一のファイルに書いておいて、その中のanonymous namespaceにユーティリティを置くか。
お礼
ありがとうございます
補足
既存ソースの作りが、 typeidでactual typeを調べなければならなかったり、 目視で、どの型でインスタンス化しているかを確認しなきゃいけなかったりする点、 私は、かなり悲しみに暮れています(;_;) ただ、 「メイヤーの開放/閉鎖原則」によれば、 実装は継承によって再利用可能だが、 新しいクラスは既存のインタフェースを必ずしも引き継ぐ必要はないとのことなので、 インタフェースの増減は別にいいかなぁとは思っています。 私の解釈ですが、 例えば、 「車クラス」で、 「キーを指す」「エンジンをかける」「ギアを入れる」「アクセルを踏む」「ハンドル操作する」のメソッドがあったとき、 「未来の車クラス」では、 「発信ボタン」のメソッドだけがあれば良かったりするケースもあったりするのかなぁ。と思います。 「柔軟性」と「簡便化」のトレードオフになると思いますが、「簡便化」を重視するなら、ユーザには、色んなメソッドや色んなプロパティを「意識させない作り」というのもありなのかなぁと。 /*************************/ 以下2点は、具体的にはどういうことになりますでしょうか? > それよりも例えばユーティリティ的な > モジュールを作ったほうが良くないですか。 > 2つのクラスとも単一のファイルに書いておいて、 > その中のanonymous namespaceにユーティリティを置くか。 今、自分は、渡されたスーパークラス群を使って、 サブクラスを作るような状況なのですが、 スーパークラスに手を入れずに書ける方法でしょうか? 無名名前空間を使うと、同一ファイル内からは見えるけど, 他のファイルからは見えないような変数を宣言ができるとは思いますが、基本、各クラスのプロパティはprivate で書かれているので、使えるスコープは一応狭い状況です。 (※どのクラスを実体化しているかはわからないので、どのクラス階層で持っているどんなプロパティなのかは、追うのは物凄ーく苦労しますが、、、) .
お礼
> 本当は、これがデメリットに思えるようなら、 > そもそもクラスの設計が良くない >(オブジェクト指向的になってない)ってことな気もしますが。。 ですよね!(泣) 部品を使うユーザが、作られている部品の隅々までを把握しなければならないというプログラムは、余り望ましくないのかなと私も考えます。 処理の詳細は隠蔽し、その処理を簡便に行うための必要最小限のIN/OUTを、提供するのが良い設計と考えます。 > RTTIとか有効にすれば、とりあえず、 > どの型が突っ込まれているかは分かるようになるのでは。 ありがとうございます! typeid演算子で、type_info型の変数に突っ込んで、 typeid (*p).name() をデバッグモードのログに履いて、確認しながらリバースエンジニアリングしていこうと思います!