C++のクラスを継承できないように設計

2929 ワード

avaには継承できない種類があります.それはfinal類です.C++にはfinalクラスはありません.
C++は継承できないクラスを実現するには多くの方法がある.主な考え方は、子類が親類の部分を構築できないようにすることであり、このような類は子類全体を実例化することはできない.これによりサブクラスの継承が制限する.だから私达は父类の构造関数を宣言して私有になることができて、しかしこのように父类は実例化することができなくて、引き続き考えて、、、私达は友员が受け継ぐことができない特性を利用することができます!まずCParentを継承することができないと仮定する.CParentをあるクラスのメンバとサブクラスとする、CParentは構築可能であるが、CParentのサブクラスCChildはそのメンバの特性を継承できないので構築できない.CFInalClassMixinを導入しました私たちはこのクラスの機能に対してこのように期待しています:いかなるクラスもそれから継承してインスタンス化することができなくて、同時にこのクラス自身もそれがインスタンス化されることを望んでいません.1つの構造関数と構造関数がprivateのクラスであることを実現すればよい.同時にこのような中で私たちのCParentを友員として声明します.コードは以下の通りである:class CfinalClassMixin{friend class CParent;private:CfinalClassMixin(){}~CfinalClassMixin(){}};//私たちのCParentコードは以下の通りです:class CParent{public:CParent(){}~CParent(){}}このクラス(注、この場合も継承可能)は、継承できない必要があります.コードをclass CParent:public CFInalClassMixin{public:CParent(){}~CParent(){}}に変更すれば、いいですよ.次に、CParentからサブクラスを継承してclass CChild:public CParent{}を試します.コードをコンパイルしてみると、何の役にも立たない!次に、Mixinクラスのコンストラクション関数に親がアクセスできるようにするが、サブクラスはアクセスできないという、このスキームの原理を考えてみましょう.私たちのコードを見てみると、親はCFInalClassMixinクラスの友达で、その構造関数にアクセスすることができます.メンバーは継承できないため、CChildはCFInalClassMixinのコンストラクタにアクセスできない.だからインスタンス化できないはずだ.CChildは確かにCFInalClassMixinのコンストラクション関数にアクセスできませんが、呼び出す必要はありません.これが問題の原因だと思います.CChildはCParentを通じてCFInalClassMixinを構築しているので、この友达は彼に何の役にも立たない!今問題が見つかりました.解決するのは簡単だ.CChildがCFInalClassMixinのコンストラクション関数を呼び出さなければならない限り、どのようにして目的を達成することができますか?虚の継承を覚えていますか?虚継承の特徴の一つは,虚ベースクラスの構造関数が最終サブクラスによって構築されることである.したがって、CParentをCFInalClassMixinからCFInalClassMixin虚から継承するように変更すればよい.コードは以下の通りである:class CParent:virtual public CFInalClassMixin{public:CParent(){}CParent(){}}今やってみよう、いいよ.しかし、多くの継承に動悸を覚える人もいるかもしれません.しかし、私たちのところではそんなに心配する必要はありません.どうして?私たちのCFInalClassMixin類は純粋だから!pure! つまり、メンバー変数はまったくありません!多くの継承がもたらす最大の問題を心配する必要はありません菱形継承によるデータ冗長性および二義性今はまだ足りない!それは私たちがこのCFInalClassMixinクラスを使うたびに、あるクラスの友达に声明を加えることはできません.これはなんと面倒なことか.大きな問題ではありませんが、私はやはり解決しなければならないと思います.私はC++を十分に信頼しているからです.解決策も簡単!それはテンプレートを使うことです!具体的な説明は省略しますが、コードを与えると、以下が私のテストプログラムの完全なコードであることがわかります(その中のCFInalClassmixinはテンプレートに変更されています)
#include "stdafx.h"
#include <iostream>
using namespace std;

template<class T>   //    
class CFinalClassMixin
{
	friend T;

	private:
	CFinalClassMixin(){}
    ~CFinalClassMixin(){}
};

		
class CParent:virtual public CFinalClassMixin<CParent>  //   
{
	public:
	  CParent(){}
	  ~CParent(){}
};

class CChild:public CParent{}; //      

int main(int argc, char* argv[])
{
	CParent a; //     
	CChild b; //    
	return 0;
}

今は継承されたくないクラスにCFInalClassMixinブレンドクラスを加えて親にすればよい. 
構造関数を制限することによって、私たちは継承を制限する目的を達成した.
しかし、これは静的関数ばかりのクラスのような例外である.これらのクラス自体は構造を必要としない.だから私たちはそれに方法がありません.しかし、多くの場合、静的関数ばかりのクラスは、プログラム自体の設計が考慮される可能性があることを多少示唆している.
実はこれはMixin類(混合類)が使用する小さな例にすぎない.他にも多くの用途がありますあまり言わないでください.私が説明したいのは、多くの継承に反感を持っているかもしれません.しかし、あまり否定しても損はない.現在、マルチ継承を使用すべきかどうかは議論の段階にある.一つの方法が適切に使われているかどうかは、やはり使う人にかかっていると思います.