1

シングルトン パターンを学習しようとしていますが、設計上のジレンマに直面しています。

動作するシングルトンは次のようになります。static myClass * mc; に注意してください。public static myClass * getInstance と同じように公開されます

1) ワーキングコード

#include "iostream"
using namespace std;

class myClass {
private:  
   myClass() {          
   }
 void   operator = (const myClass &);
 myClass (const myClass & );

public:
   static myClass * mc;
   static myClass * getInstance () {
       cout << "\n getInstance  callsed \n";
       if (mc == NULL) {
           mc = new myClass();
       }
       return mc;
    }

 void print() {
     cout <<"\n call to print donem \n";
 }

};
myClass * myClass::mc =NULL;

int main() {    
    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

2) NOT_WORKING_CODE

コンパイラ エラーを発生させるインスタンスが動作していません。static myClass * mc;私はプライベートとして保持しようとしたことに注意してください

#include "iostream"
using namespace std;

class myClass {
private: 
   static myClass * mc;
   myClass() {        
   }
 void   operator = (const myClass &);
 myClass (const myClass & );

public:
    static myClass * getInstance () {
        cout << "\n getInstance  callsed \n";
        if (mc == NULL) {
            mc = new myClass();
        }
        return mc;
    }

 void print() {
    cout <<"\n call to print donem \n";
 }

};

int main() {

    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

出力: 関数main': undefined reference tomyClass::mc で、`myClass::mc' への未定義参照

問題 :

1) 上記の NOT_WORKING_CODE でエラーが発生するのはなぜですか

2) public myClass::mc を使用することは、インターフェイスのみを public にする必要があるため、設計規則に反すると思います。ここで私が直面している問題は、上記の作業コード 1) のユーザーが myClass::mc に直接アクセスして、print myClass::mc->print(); のような関数を呼び出す可能性があることです。最初にインスタンスを呼び出さずに..

つまり、上記の1)で次を変更したとき

int main() {
    myClass::mc->print();
    myClass * mc = myClass::getInstance ();
    mc->print();
    return 0;
}

それが印刷されたとき、私はぞっとしました

call to print donem 

 getInstance  callsed 

 call to print donem 

つまり、インスタンスが で作成されたので、有効なインスタンスなしで呼び出すことができましたgetInstance。これは、印刷がいくつかのポインターなどにアクセスしていた場合、例外が発生した可能性があることを意味します。

したがって、これは 1) に設計上の欠陥があることを示しています。同じことを修正する方法は問題です...

4

2 に答える 2

2

//myClass * myClass::mc =NULL; 変数をプライベートにしたためではなく、その行をコメントアウトしたためにエラーが表示されます。したがって、コードを変数 private で機能させるには、その行をコメントアウトしないでください。コンパイルされます。

ここを参照してください:未定義の参照/未解決の外部シンボル エラーとは何ですか? どうすれば修正できますか?

ただし、シングルトン パターンをこのように使用しないでください。実際、シングルトンの使用をまったく避けてください。本当に使用する必要がある場合は、マイヤーズ シングルトンを使用してください (ググってください!)。

于 2013-05-27T06:46:21.313 に答える
1

mcは静的データ メンバーであるため、最初のケースで行ったように明示的に初期化する必要があります。

myClass * myClass::mc =NULL;

2 番目のケースでは、これを実行できませんでした。

このリンクを参照してくださいhttp://www.parashift.com/c++-faq/link-errs-static-data-mems.html

ところで、これはコンパイラ エラーではなくリンカ エラーです。

于 2013-05-27T06:59:03.257 に答える