C++プライベート構造関数の役割


多くの場合、現在のプログラムにobjectが1つしかないことが要求されます.たとえば、1つのプログラムにはデータベースとの接続が1つしかなく、マウスのobjectが1つしかありません.通常、コンストラクション関数の宣言をpublicセグメントに配置します.privateセグメントに配置すると、どのような結果が発生しますか?これは何を意味しますか?プログラムでオブジェクトを宣言すると、コンパイラはコンストラクション関数(ある場合)を呼び出します.この呼び出しは通常外部で、つまりclassオブジェクト自体の呼び出しではありません.コンストラクション関数がプライベートである場合、class外部でプライベートメンバーへのアクセスが許可されないため、コンパイルエラーが発生します.しかしながら、class自体については、classオブジェクトとは独立しているため、オブジェクトを生成する必要もなく使用することもできるstatic共有メンバーを利用することができる.この場合、コンストラクション関数はclassによってプライベート化されるため、オブジェクトを作成するにはclassのプライベートドメインにアクセスできる必要があります.この点はclassのメンバーだけができる.しかし、オブジェクトを構築する前に、どのようにしてメンバーを利用することができますか?staticにはclassオブジェクトとは独立して存在する共通のメンバーがあり、「我々」はアクセスできます.static関数でclassのオブジェクトを作成し、参照またはポインタとして返した場合(ここではオブジェクトではなく、主にコンストラクション関数がプライベートであり、外部では一時オブジェクトを作成できない)、このオブジェクトの使用権が得られます.次に例を示します.
class OnlyHeapClass
{
public:
   static OnlyHeapClass* GetInstance()
       {
              //     OnlyHeapClass        
              return (new OnlyHeapClass);
       }
   void Destroy();
private:
       OnlyHeapClass() { }
       ~OnlyHeapClass() {}
};
int main()
{
       OnlyHeapClass *p = OnlyHeapClass::GetInstance();
       ... //   *p
       delete p;
       return 0;
}

この例ではプライベートコンストラクション関数を使用し、GetInstance()はOnlyHeapClassの静的メンバー関数としてメモリにオブジェクトを作成します.関数間で伝達され、値伝達方式が使用できないため、getInstance()が終了してもオブジェクトは解放されず、手動で解放されます.コンストラクション関数のプライベート化されたクラスの設計は、他のクラスがこのクラスから派生したり、クラスのインスタンスを作成したりすることができないことを保証します.また、たとえば、メモリに最大1つのclassを実装します.または、指定数のオブジェクト(classのプライベートドメインにstaticタイプのカウンタを追加できます.初期値は0に設定し、GetInstance()で制限します.呼び出すたびにカウンタの値がオブジェクトの個数の上限値に達しているかどうかを確認し、そうであればエラーが発生します.そうでなければ、newは新しいオブジェクトを生成し、カウンタの値を1増加します.最後に、値のコピー時に新しいオブジェクトのコピーが生成されないように、コンストラクション関数をプライベートに設定するほか、レプリケーションコンストラクション関数も特に宣言してプライベートに設定します.コンストラクション関数をProtectedとして設計すれば、同様の目的を達成することもできるが、継承することができる.
また、スタック上でnewの新しいクラスオブジェクトしか保証できないことをどのように保証しますか?構造関数をプライベートメンバーとして定義するだけです.なぜなら、C++は静的バインド言語であるからです.コンパイル中に、すべての非虚関数呼び出しを分析する必要があります.虚関数でもアクセス性を確認する必要があります.したがって、スタック上でオブジェクトを生成すると、オブジェクトは自動的に解析され、すなわち、解析関数にアクセスできる必要があります.一方,スタック上でオブジェクトを生成するには,析出タイミングがプログラマによって制御されるため,必ずしも析出関数は必要ない.スタック上でオブジェクトを生成できないことを保証した後、スタック上で生成できることを証明する必要があります.ここでOnlyHeapClassと一般オブジェクトの唯一の違いは、その構造関数がプライベートであることです.delete操作では、構造関数が呼び出されます.だからコンパイルできません.どうやって解放しますか?答えも簡単で、メンバー関数を提供してdelete操作を完了します.メンバー関数では、構造関数にアクセスできます.もちろんdetele操作もコンパイルできます.  void OnlyHeapClass::Destroy() {          delete this;}コンストラクション関数のプライベート化されたクラスの設計は、newコマンドでスタック内でのみオブジェクトを生成でき、動的にオブジェクトを作成できることを保証し、オブジェクトのライフサイクルを自由に制御できます.ただし、このようなクラスは、作成および取り消しの共通インタフェースを提供する必要があります.またdeleteをリロードし、newはプライベートでオブジェクトをスタックに作成する目的を達成することができ、placement newでスタックに作成することもできます.
------------------------------------------------------------------------------------------------------------------------------------------------------なぜ自分で呼び出すのですか?オブジェクトが生存期間を終了すると、構造関数が自動的に呼び出されるのではないでしょうか.どのような場合に構造関数を自分で呼び出す必要がありますか?========================================================================================================================================このようにして、人はあなたのこの関数を呼び出してオブジェクトを分析するしかなく、それによって分析する前に必ずあなたの要求した動作をすることを保証しました.          2.スタックオブジェクトのみを生成するのにどのような場合に役立ちますか?======================================スタックオブジェクトは、スタックオブジェクトに対してnewである.どのような場合にnewが必要で、どのような場合にスタック内で事前に割り当てられるかは、いつ動的に、いつ静的に生成すべきかの問題にほかならない.これは具体的な状況に応じて具体的に分析しなければならない.たとえば、1つの関数でオブジェクトが最大10個しかないことを事前に知っておくと、このオブジェクトの配列を定義することができます.10個の要素で、各要素はスタックオブジェクトです.数値を特定できない場合は、このオブジェクトのポインタを定義し、作成する必要があるときにnewを出てlistまたはvectorで管理することができます.-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------構造関数をプライベートとして定義すると,クラスドメイン外での構造関数の使用が阻止される.これは、1.このタイプの変数を定義できません.つまり、スタックメモリ領域内でこのタイプのオブジェクトを作成できません.オブジェクトを作成するには、newでスタック上でのみ実行できます.          2. プログラム内でdeleteを使用してこのタイプのオブジェクトを削除することはできません.オブジェクトの削除はクラス内でのみ実現でき,すなわちクラスの実装者のみがオブジェクトに対するdeleteを実現でき,ユーザは勝手にオブジェクトを削除できない.ユーザがオブジェクトを削除したい場合は,クラスの実装者が提供する方法に従うしかない.このようにすると、ユーザーの使用が大幅に制限されることがわかります.一般的にはそうしないでください.通常、singletonの実装など、特殊な目的を達成するために使用されます.スレ主はsingletonの資料を探して、それがどういうことなのかを知ることができます.