みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

オブジェクト指向

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

投稿日時 - 2008-06-28 00:35:46

QNo.4134542

困ってます

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

変数を基準に考えてるのではオブジェクト指向になりません。オブジェクトの中でどのような操作が行われているかは、外からすれば気にしないで良いように設計するべきです。
オブジェクトが外に公開するのは、その操作(実装で言えばメンバ関数)です。どのような操作をそのオブジェクトは提供するか、という視点で考えてみてください。

例えば複素数クラスであれば、
 ・足し算可能
 ・掛け算可能
 ・コピー可能
 ・偏角・絶対値取得
 ・Re・Im取得
などを使えれば十分でしょう。このように、使用させる操作だけ公開しておけば、中の変数が(x,y)で管理されていたとしても(r,θ)で管理されていたとしても外から見れば関係ありません。

基本的には、内部の変数そのものは外からタッチさせないものです。

投稿日時 - 2008-06-28 02:17:48

補足

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

投稿日時 - 2008-06-28 02:24:48

お礼

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

投稿日時 - 2008-06-28 02:34:05

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

> 動的初期化というのは、必要に応じて初期化する行為を指すのでしょうか。それとも動的変数の初期化を指すのでしょうか?

どちらでもありません。
動的初期化というのは、非局所オブジェクト(関数の外で定義したオブジェクト。静的データメンバもこれにあたる)のうち、明示的なコンストラクタを持つものや、定数式以外の初期化子を持つものの初期化です。
例えば、

struct A
{
 A();
};

A a; // 明示的なコンストラクタを持つので動的初期化
int b = func(); // 定数式以外の初期化子を持つので動的初期化

という具合です。
動的初期化が行われる順序は、同じ翻訳単位内では上から順番なのですが、翻訳単位をまたがった場合の順序は不定になります。
こういったものは静的データメンバにしない方が無難です。

投稿日時 - 2008-06-29 01:31:54

お礼

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

投稿日時 - 2008-06-30 15:32:02

ANo.5

非静的データメンバは、すべてprivateにするか、すべてpublicにするかのどちらかです。すべてpublicにするのは集成体かそれと同等の用途の場合です(例えば、明示的なコンストラクタがあっても、用途が集成体と同じ場合など)。

静的データメンバはケースバイケースですが、そもそも動的初期化が必要なものは静的データメンバにはしない方が無難ですね。

やや余談ですが、仮想関数は原則としてprivateにし、派生クラスから呼び出される可能性があるもの(それを前提とした設計にんっているもの)のみprotectedにします。つまり仮想関数はpublicにはしません(NVIイディオムまたはNVIパターンで検索してください)。

getterやsetterの類は必ずしも必要ではありません。クラスのメンバ関数はデータメンバを直接操作せざるを得ない最小限のものに限定し、非メンバ・非friendの関数にできるものは原則そのようにします。
何でもかんでもメンバ関数にしようとすると、getterやsetterを用意しないと厳しくなります(データメンバがグローバル変数に近くなるので)。

投稿日時 - 2008-06-28 10:56:52

お礼

>静的データメンバはケースバイケースですが、そもそも動的初期化が必要なものは静的データメンバにはしない方が無難ですね。

 動的初期化というのは、必要に応じて初期化する行為を指すのでしょうか。それとも動的変数の初期化を指すのでしょうか?

投稿日時 - 2008-06-29 00:46:41

ANo.3

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

アクセサ(getter、setter)を作成するのは。初めは非効率に思えるかも知れませんが、キャリアを積むと「作成しない方が非効率である」事がわかると思います。

投稿日時 - 2008-06-28 02:05:19

補足

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

投稿日時 - 2008-06-28 02:23:44

お礼

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

投稿日時 - 2008-06-28 02:33:02

ANo.2

>Setなんたら()、Getなんたら()というメンバ関数を大量につければ
つけてはいけません。そんなことをする位なら変数を公開した方がマシです。

>一応変数は全部privateでもできるようですが・・・。
オブジェクト指向というからには、オブジェクトとそのオブジェクトに対して可能な操作だけを公開して下さい。

投稿日時 - 2008-06-28 01:07:53

お礼

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

投稿日時 - 2008-06-28 01:19:08

ANo.1

変数は極力privateにすべきです。

Set()やGet()はprivateの意味がかなり薄れます。
publicよりはましかも知れませんが。

classの意味の大きな部分にカプセル化という概
念があります。publicはカプセル化を崩します。

設計のあり方でprivateにしますが、privateにす
ると、どうしても効率が悪くなる場合は、その時
点の設計力の限界と割り切ってpublicも致し方が
無いでしょう。基本方針は基本方針ですが、こだ
わり続けるのは非効率でしょう。

投稿日時 - 2008-06-28 00:49:05

補足

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

投稿日時 - 2008-06-28 01:13:32

お礼

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

投稿日時 - 2008-06-28 02:52:41

あなたにオススメの質問