2013-10-29 58 views
0

這是單例模式的例子嗎?如果不是這樣,那麼如果我們將這個類用作記錄器,會出現什麼問題。 (當然它不是一個完全靈活的記錄器)這是單身模式的例子嗎?

#include <iostream> 
#include <fstream> 
using namespace std; 


class logger 
{ 
    private: 
     static ofstream myfile; 

     void openfile() 
     { 
      myfile.open ("example.txt"); 
     } 
     void closefile() 
     { 
      myfile.close(); 
     } 
    public:  
     void logit(string str) 
     { 
      if (myfile.is_open() == 1) 
      { 
       myfile << str << endl; 
      } 
      else 
      { 
       openfile(); 
       myfile << str << endl; 
      } 
     } 
}; 

ofstream logger::myfile; 
int main() 
{ 
    logger l; 
    l.logit ("log from vod application"); 
    logger l2; 
      l.logit ("log from guide application"); 

    logger l3; 
    l1.logit ("log from application 3-1"); 
    l1.logit ("log from application 3-2"); 

      return 0; 
} 

任何討論將有所幫助。

Devesh

+1

不,這不是因爲它有一個公共構造函數 –

+0

它不是一個單身人士,你可能會遇到的問題是,如果文件在問題運行時被移除/移動/篡改,它將不會被重新創建。但是這個問題與其單例性或缺乏性沒有多大關係。 –

+0

這或多或少是Meyer的singleton版本,其中唯一的實例是myfile,並且您沒有getInstance方法,而是直接訪問logit()。如果logit是靜態的 –

回答

1

它不可能是一個單身:

  1. 那裏是你的代碼1它實例
  2. 的類有簡單的創建一個新的公共構造實例
+1

它可以是singleton就好了。它只是不遵守singleton *模式*,它確保它*必須*是單身人士:-) –

+0

然後它是單身人士('logger :: myfile')的包裝 – wl2776

+0

記錄器:myfile不是單身人士:單例模式將類限制爲單個實例,並提供對該實例的全局訪問。 – Pete

3

不,這不是一個單身人士。

要創建一個單例,必須使構造函數爲私有。你的類沒有聲明任何構造函數,因此編譯器會生成默認的構造函數。這是不好的,因爲會有複製構造函數和賦值運算符,它們只是簡單地複製所有成員。如果您將打開的文件或指針的句柄複製到分配的內存並嘗試使用副本進行操作,通常會發生不好的事情。

class logger { 
    static logger* the_logger; 
    // other private members 

    logger() : the_logger(NULL) 
     { /*logger construction*/} 
public: 
    static logger* logger::instance(const string& filename) { 
     if (the_logger == NULL) { 
      the_logger = new logger(/*arguments*/); 
     } 
     return the_logger; 
    } 

    static void cleanup(void) { 
     delete the_logger; 
    } 
    /* other public members*/ 
    void debug(...) 
} 


int main(void) 
{ 
    logger::instance()->debug(blah-blah-blah); 
    logger::cleanup(); 
} 

爲了簡單起見,我已經跳過了代碼,有關共享資源(文件描述符或輸出流)的同時訪問。另外,如果我沒有記錯的話,你的代碼將不會編譯,因爲靜態成員只能用靜態成員函數訪問。

+0

這不是用C++實現單例反模式的最好方法。使用'靜態記錄器和記錄器::實例(){靜態記錄器the_logger(/ *參數* /);返回記錄器; }'。 – Simple

+0

如果我想調整實例的參數該怎麼辦?在提議的實現中,它被聲明爲函數內部的靜態變量。 – wl2776

+0

然後將它們作爲參數傳遞。關鍵是你不應該使用'new'或指針。 (靜態記錄器和記錄器::實例(std ::字符串常量和文件名){靜態記錄器the_logger(文件名);返回記錄器; }'。 – Simple