• ベストアンサー

オブジェクト指向

 C++ではクラスがありますが、このクラスで「公開(public)」「非公開(private)」キーワードがあります。クラスが変数を持つ場合、どういった変数を公開にしておき、どういった変数を非公開にしておくべきでしょうか。  Setなんたら()、Getなんたら()というメンバ関数を大量につければ一応変数は全部privateでもできるようですが・・・。なんか非効率的な気がします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

変数を基準に考えてるのではオブジェクト指向になりません。オブジェクトの中でどのような操作が行われているかは、外からすれば気にしないで良いように設計するべきです。 オブジェクトが外に公開するのは、その操作(実装で言えばメンバ関数)です。どのような操作をそのオブジェクトは提供するか、という視点で考えてみてください。 例えば複素数クラスであれば、  ・足し算可能  ・掛け算可能  ・コピー可能  ・偏角・絶対値取得  ・Re・Im取得 などを使えれば十分でしょう。このように、使用させる操作だけ公開しておけば、中の変数が(x,y)で管理されていたとしても(r,θ)で管理されていたとしても外から見れば関係ありません。 基本的には、内部の変数そのものは外からタッチさせないものです。

Yotunohira
質問者

お礼

 すみません、お礼が補足になっていました。

Yotunohira
質問者

補足

 操作だけを考えてクラスを作るというのは難しいですね。オブジェクト指向を学ぶ際にお勧めの書籍があれば教えてください。

その他の回答 (5)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

> 動的初期化というのは、必要に応じて初期化する行為を指すのでしょうか。それとも動的変数の初期化を指すのでしょうか? どちらでもありません。 動的初期化というのは、非局所オブジェクト(関数の外で定義したオブジェクト。静的データメンバもこれにあたる)のうち、明示的なコンストラクタを持つものや、定数式以外の初期化子を持つものの初期化です。 例えば、 struct A {  A(); }; A a; // 明示的なコンストラクタを持つので動的初期化 int b = func(); // 定数式以外の初期化子を持つので動的初期化 という具合です。 動的初期化が行われる順序は、同じ翻訳単位内では上から順番なのですが、翻訳単位をまたがった場合の順序は不定になります。 こういったものは静的データメンバにしない方が無難です。

Yotunohira
質問者

お礼

 こうしたものを動的初期化と呼ぶのですか。  静的データメンバは定数で初期化するようにします。ありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

非静的データメンバは、すべてprivateにするか、すべてpublicにするかのどちらかです。すべてpublicにするのは集成体かそれと同等の用途の場合です(例えば、明示的なコンストラクタがあっても、用途が集成体と同じ場合など)。 静的データメンバはケースバイケースですが、そもそも動的初期化が必要なものは静的データメンバにはしない方が無難ですね。 やや余談ですが、仮想関数は原則としてprivateにし、派生クラスから呼び出される可能性があるもの(それを前提とした設計にんっているもの)のみprotectedにします。つまり仮想関数はpublicにはしません(NVIイディオムまたはNVIパターンで検索してください)。 getterやsetterの類は必ずしも必要ではありません。クラスのメンバ関数はデータメンバを直接操作せざるを得ない最小限のものに限定し、非メンバ・非friendの関数にできるものは原則そのようにします。 何でもかんでもメンバ関数にしようとすると、getterやsetterを用意しないと厳しくなります(データメンバがグローバル変数に近くなるので)。

Yotunohira
質問者

お礼

>静的データメンバはケースバイケースですが、そもそも動的初期化が必要なものは静的データメンバにはしない方が無難ですね。  動的初期化というのは、必要に応じて初期化する行為を指すのでしょうか。それとも動的変数の初期化を指すのでしょうか?

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.3

がると申します。 んと…きちんとした「オブジェクト指向プログラミング」をするのであれば。 ・変数は全てprivate ・全ての変数にgetter、setterを作る。ただしそれがpublicなのかprotectedなのかはクラス次第 はほぼ鉄則だと思ってください。 ちなみに当然ではありますが「自分のclass内変数を触るときもgetter、setter経由」にしましょう。 後々の、保守メンテナンス性が根底から変わりますので。 アクセサ(getter、setter)を作成するのは。初めは非効率に思えるかも知れませんが、キャリアを積むと「作成しない方が非効率である」事がわかると思います。

Yotunohira
質問者

お礼

すみません、お礼が補足に入っていました・・・。

Yotunohira
質問者

補足

 getter,setterでググると、参考になるサイトが見つかりました。  僕は個人の好きでやってるので、そうした保守などの必要性が低いですが、後々の変更に耐えうるクラスを設計する場合にはsetter,getterを取り入れようと思います。ありがとうございました。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

>Setなんたら()、Getなんたら()というメンバ関数を大量につければ つけてはいけません。そんなことをする位なら変数を公開した方がマシです。 >一応変数は全部privateでもできるようですが・・・。 オブジェクト指向というからには、オブジェクトとそのオブジェクトに対して可能な操作だけを公開して下さい。

Yotunohira
質問者

お礼

 やっぱりSet、Getはつけない方がいいんですね。操作系の変数はその変数の使い方を良く考えてから公開か非公開か決めようと思います。ありがとうございました。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

変数は極力privateにすべきです。 Set()やGet()はprivateの意味がかなり薄れます。 publicよりはましかも知れませんが。 classの意味の大きな部分にカプセル化という概 念があります。publicはカプセル化を崩します。 設計のあり方でprivateにしますが、privateにす ると、どうしても効率が悪くなる場合は、その時 点の設計力の限界と割り切ってpublicも致し方が 無いでしょう。基本方針は基本方針ですが、こだ わり続けるのは非効率でしょう。

Yotunohira
質問者

お礼

すみません、お礼が補足になっていました。

Yotunohira
質問者

補足

効率が良い場合はpublicで割り切りたいと思います。ありがとうございました。

関連するQ&A