100-59

1837 ワード

59.継承できないクラス(構文).テーマ:C++で継承できないクラスを設計します.
分析:これはAdobe社の2007年のキャンパス募集の最新の筆記試験問題です.この問題は応募者のC++の基本的な基礎を考察する以外に、反応能力も考察することができて、とても良いテーマです.
考え方:
この問題は、最初は奇抜に見えた.私のような初心者にとって本当にそうです.私が最初にこの問題を見たとき、基本的には考えられませんでしたが、後で考えてみると、Effective c++で似たような説明を見たことがあります.コンパイラで自動的に生成したくない関数があれば、明確に指摘しなければなりません.上記の方法は、これらの関数をプライベート関数として宣言することです.そこで、あるクラスのコンストラクション関数とコンストラクション関数をプライベートとして宣言すると、新しいクラスが継承され、新しい変数が宣言されると、親のコンストラクション関数が呼び出せないため、コンパイラがエラーを報告すると思います.これは、コンパイルフェーズでエラーを発生させるよりも、実行時にエラーを発生させるほうがはるかに良いためです.のそこで,やると言えばやる,単純にコンストラクション関数とコンストラクション関数をプライベートと宣言すればよい.
しかし、菜鳥は菜鳥で、このような問題はまさかこのように解決したと思っていますか?自信なくまたjuly大神の解答を調べました.次のような参考になりました.
// Define a class which can't be derived from 
template <typename T> class MakeFinal 
{ 
      friend T; 
private: 
      MakeFinal() {} 
      ~MakeFinal() {} 
};
class FinalClass2 : virtual public MakeFinal<FinalClass2> 
{ 
public: 

      FinalClass2() {} 
      ~FinalClass2() {} 

};
では、このようなサブクラスを定義すると、コンパイルエラーが発生します.
class Try : public FinalClass2 
{ 

public: 
      Try() {} 

      ~Try() {} 
};

このクラスは一般的なクラスと変わらず、スタック上にインスタンスを作成することもできます.クラスMakeFinalのコンストラクション関数とコンストラクション関数はすべてプライベートですが、クラスFinalClass 2はその友元関数であるため、FinalClass 2でMakeFinalのコンストラクション関数とコンストラクション関数の両方を呼び出す
コンパイルエラーは発生しません.しかし、FinalClass 2からクラスを継承してインスタンスを作成しようとすると、コンパイルによって異なります.クラスFinalClass 2はクラスMakeFinal虚から継承されているため、Tryのコンストラクション関数を呼び出す際にFinalClass 2を直接スキップしてMakeFinalのコンストラクション関数を直接呼び出す.残念なことに、TryはMakeFinalの友元ではないため、プライベートなコンストラクション関数を呼び出すことはできません. 
以上の解析に基づいてFinalClass 2から継承しようとしたクラスは、インスタンス化されるとコンパイルエラーが発生するため、FinalClass 2は継承できません.これは私たちの設計要求を満たしています.