C++の話です
class Base{.....};
class Derived1 : public Base{.....};
class Derived2 : private Base{.....};
と書くことができますが、public継承とprivate継承にはそれぞれ意味がありますよね。
public継承は"is-a"関係を意味していて、private継承は
"is-implemented-in-terms-of"関係を表していると言います。
public継承を実際に動くプログラムは思いつくのですが、private継承を使ったプログラムが思いつきません(というより有効に使えません)
派生クラスから呼び出せない、外部からも呼び出せないメンバをどう使うのでしょうか?
No.3ベストアンサー
- 回答日時:
> 基底クラスの段階でのprivateと継承してからの段階でprivate
> 扱いになるのとでは意味が違うのでしょうか?
継承時のアクセス制限は、いうなれば「継承する側の都合」なので、
「継承する自分自身を"呼ぶクラス"や自分自身より"下位の派生クラス"」に影響します。
privateで継承したクラス自身はこの影響を受けずに、
自分自身は基底クラスの方の影響だけを受けるということです。
定義も派生する側に書きますよね。
同じ基底クラスからでも継承するクラス毎に別設定できるということです。
# なので、他のクラスの一部実装だけを流用するためにprivateで実装継承なんてこともありえるのです。
# publicで継承すると余計なインターフェイスまで取り込んじゃいますが、
# privateなら内部で利用するだけですから余分なものがあっても自分が使うだけで、外には漏らしません。
# (private継承できない時/言語では、変わりに「委譲」することが多いです)
# (例えばJavaとかはサブクラス側で狭めることはできないですが、C++は必要に応じて選択肢が多い、と。(その分複雑ともいう))
一方、基底クラス側のアクセス制限は「規定クラスの都合」なので、
継承する自分自身も「基底クラスの外、より下位の派生」ですから、privateの影響を受けます。
これを勝手にサブクラスが変更することは、当然できません。
> 派生クラスから呼び出せない、外部からも呼び出せないメンバをどう使うのでしょうか?
本題に戻ると、private継承であれば継承したクラス自身は(自分だけ)使えますし、
privateなメンバであれば自分だけは使えますので、自分専用の内部実装を書くのが基本かと。
# ちなみに、C++のprivate:はあくまで「クラスの"呼び出し制限"」なので、例えばこんなことも可能。
/** 純粋仮想関数を含む基底クラス */
class Foo {
private:
/** 内部実装はサブクラスに要請 */
virtual void doSomething() = 0; /* 呼び出しはprivateなのに実装は純粋仮想 */
public:
/** 外部インターフェイスは持つ */
void do(){ doSomething(); } /* このクラス内からしか呼べないようにdoSomethingはprivate */
}
/* 継承したサブクラスは、Foo::doSomethingを呼べないのに実装は定義しなければならない */
解説ありがとう御座いますm(__)m
「継承する側の都合」ですか。
コードを使用する側に余計なものを触らせない便利な機能ですね.....
もっと研究してみます。
No.4
- 回答日時:
「Effective C++ 第3版」の39項「private継承は賢く使おう」に、ご質問の内容について詳しく触れられていますよ。
なんと「Effective C++ 第3版」の39項「private継承は賢く使おう」に書いてあることがよく分からなかったので、ここで質問したという経緯がございます('A`)
No.2
- 回答日時:
ポリシークラスと呼ばれる技法を使うときに、private/protected継承を使うことがあります。
ポリシークラスについてはModern C++ Designを参照して下さい。「1.7章 ポリシー・クラスのデストラクタ」でprivate/protected継承を推奨しています。
Modern C++ Designですね。読んでみようと思います。
ちょっと不思議に思ったのですが、private継承は基底クラスの全てのメンバをprivateで継承しますよね。
基底クラスのpublicの部分のメンバももちろんprivateで継承しますが、派生クラス先からアクセスできますね。
しかし、基底クラスでprivateにしていると派生クラスからアクセスできません。
基底クラスの段階でのprivateと継承してからの段階でprivate扱いになるのとでは意味が違うのでしょうか?
class Base
{
public:
void puB_Func(); //private継承しても派生クラスからアクセス可
private
void pr_BFunc(); //どう継承してもアクセス不可
};
No.1
- 回答日時:
例えば、「実装継承」等に使います。
オブジェクト指向(OO)では一般的によくないと言われているくらいで(?)
うまく使うのは難しいかも知れませんが、C++はOO専用言語ではありませんし、多重継承もできますから、
稀に実装継承がおいしい事例もあるかと思います。
# abstractな実装等を定義しておいてprivateで実装継承すると、
# サブクラスが必要なものだけ、サブクラスのインターフェイス経由で、
# 公開することが可能ですので、多重継承できない言語では難しい用法も、
# 多重継承の利点/欠点をわかって使う手はある。
後は、代表例としてboost::noncopyableのようなイディオムでしょうか。
コピーさせないようにコンストラクタ等を非公開にするクラスですが、
よくprivate継承される例かと思います。
class Foo : private boost::noncopyable {};
返答ありがとう御座います。
boost::noncopyableはoperator=を使えないようにするんでしたっけ。
private継承の継承したクラスを隠蔽する意味が分かった気がします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【C#】クラスのコンストラクタ...
-
interface,extend,implementの...
-
デバッグ時に「Source not found」
-
setTextについて
-
抽象クラスをJUNITでテストする...
-
抽象クラスとインタフェースの...
-
Excel vbaのプログラムでガンマ...
-
VB DLLプロジェクトについて
-
cocoa、objective-cのクラスを...
-
インタフェースのstatic変数(Java)
-
インナークラスについて
-
単体テストのテストケースにて...
-
C#からDLLを呼びたいのですが・...
-
タイマーの作り方
-
Java StringBuilderクラスについて
-
肥大化した実装クラスを分割す...
-
インターフェースとは
-
Javaの自作例外クラスについて
-
javaのabstractの意味
-
インターフェース型の使い方が...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「ラッパークラス」の存在意義...
-
C# 「データが失なわれる可能性...
-
VB DLLプロジェクトについて
-
抽象クラスをJUNITでテストする...
-
「継承されたメソッドの可視性...
-
インターフェースとトレイトっ...
-
c++でのヘッダーファイルの循環...
-
JavaでのAPIの覚え方ってみさな...
-
(vba)他のアプリケーションの右...
-
ASP.NETでの共通コードの書き方...
-
なぜForm型にキャストするので...
-
vb.net 自作プロパティの削除に...
-
【C#】クラスのコンストラクタ...
-
委譲って何ですか?
-
interface,extend,implementの...
-
Javaのインスタンス化の構文の...
-
オーバーライドとラッパーの違い
-
Commons-Discovery.jarとは?
-
JTextFieldの入力制限
-
C#からDLLを呼びたいのですが・...
おすすめ情報