2

以下のコードでは、

  1. MyClass::~MyClass() デストラクタを非公開にする使用/理由/利点?
  2. デストラクタはプライベートであるため、デストラクタが最後にどのように呼び出されるか。
 // myclass.h
#include <iostream>
class MyClass {
public:
    static MyClass& GetInstance();
    void Display();
private:
    MyClass();
    virtual ~MyClass();
};
MyClass::MyClass() {
    std::cout << "Constructor " << std::endl;
}

MyClass::~MyClass() {
    std::cout << "Destructor" << std::endl;
}

MyClass& MyClass::GetInstance() {
    static MyClass _instance;
    return _instance;
}

void MyClass::Display() {
    std::cout << "Hello" << std::endl;
}

// main.cpp

#include "myclass.h"
#include <iostream>
int main() {

    MyClass::GetInstance().Display(); //case1



    std::cout << "main finished!" << std::endl;

    return 0;
}

//出力

Constructor
Hello
Destructor

// 編集

クラスのコンストラクターを公開し、GetInstance() 関数を削除した場合。

> MyClass obj;
> obj.Display();

その後、次のエラーがポップアップします

1>e:\programs\cpp_test\src\main.cpp(38): error C2248: 'MyClass::MyClass' : cannot access private member declared in class 'MyClass'
1>          e:\programs\cpp_test\static_single_test.h(11) : see declaration of 'MyClass::MyClass'
1>          e:\programs\cpp_test\static_single_test.h(6) : see declaration of 'MyClass'
1>e:\programs\cpp_test\src\main.cpp(38): error C2248: 'MyClass::~MyClass' : cannot access private member declared in class 'MyClass'
1>          e:\programs\cpp_test\static_single_test.h(12) : see declaration of 'MyClass::~MyClass

'

質問: c++ でどのように静的なケースを処理するのですか? 私的な行動を上書きしていませんか?

4

4 に答える 4

2

共有ライブラリの場合、アプリケーションができることを制限するために発生する可能性があります。

共有ライブラリを使用するアプリケーションは、エクスポートされた関数を使用してオブジェクトへのハンドルを取得し、別のエクスポートされた関数を明示的に呼び出してオブジェクトを破棄する必要があります。

これは、正当な理由のある使用契約のようなものです。DLL/so のヒープまたはデータ セグメントに存在するため、アプリケーションは割り当てを解除できません)。

そのエクスポートされた関数は、静的関数を呼び出します。何かのようなもの:

extern "C" __declspec(dllexport) MyClass* CreateMyClass() {
    return &MyClass::GetInstance();
}


extern "C" __declspec(dllexport) void     DestroyMyClass(MyClass* handle) {
    delete handle; // assumes destructor isn't private. 
    // if destructor is private, you can't use delete since it calls the destructor, which is .... private!
    handle->Destroy(); // A member function that calls the private destructor
}

MyClass::Destroy() {
    if (it_is_safe_to_destroy_the_class)
        ~Destroy();
}

ただし、Destroy() メンバー関数はパブリックにする必要があるため、この例では十分ではありません (プライベート コンストラクターの正当な理由として役立ちました)。

基本的に、クラスのユーザーがプライベートな構築および/または破棄を介して実行できることを制限したいと考えています。静的変数を介してインスタンスではなくインスタンスを「作成」し、機能(パブリックインターフェイス)のみを使用できるようにし、他のものは使用できないようにします。同様に、安全だと判断した場合は破壊します。

(編集: 私の以前の回答は私的建設に焦点を当てていたので、私的破壊のより明確な例を追加しました)

于 2013-10-18T06:36:42.113 に答える
0

投稿したクラスはシングルトンのように見えます。これは、実行ごとに 1 回だけインスタンス化できるクラスです。オブジェクトのインスタンスにアクセスできる唯一の方法が、インスタンスが 1 つだけ存在するように記述された GetInstance 呼び出しを使用することを確認するために、コンストラクターとデストラクターの両方がプライベートになります。

C++ シングルトンの設計パターン

実装では、インスタンスは静的オブジェクトです。つまり、静的オブジェクトがプログラムによってクリーンアップされると、基本的にプログラムが終了すると削除されます。

C++関数の静的変数の寿命は?

于 2013-10-18T06:52:33.853 に答える
0

privateデストラクタは、クラス自体とそのすべての のすべてのメンバ関数 (ものを含む) からアクセスできます。したがって、明らかに、それらがオブジェクトを破壊できるようにするだけであれば、デストラクタを作成することが道です。staticfriendprivate

于 2013-10-18T06:43:38.920 に答える
-1

はい、プライベート セクションにデストラクタを作成する理由があります。
オブジェクトが動的に割り当てられるだけの C++ クラスが作成されます。

この例を挙げることができます:

 #include <iostream>
  using namespace std;

  // A class whose object can only be dynamically created
  class Test
     {
      private:
        ~Test() { cout << "Destroying Object\n"; }
      public:
        Test() { cout << "Object Created\n"; }
        friend void destructTest(Test* );
 };

// Only this function can destruct objects of Test
  void destructTest(Test* ptr)
    {
delete ptr;
cout << "Object Destroyed\n";
}

  int main()
     {
   /* Uncommenting following following line would cause compiler error */
   // Test t1;

 // create an object
     Test *ptr = new Test;

 // destruct the object to avoid memory leak
destructTest(ptr);

return 0;
    }

静的オブジェクト コンパイラを作成しようとすると、エラーが発生します

于 2013-10-18T06:34:59.070 に答える