2010-09-11 28 views
2

我有輕量級模式。我有抽象類雕文。我有從字形派生的類字母和抽象代碼。我有從代碼派生的YusciiCode,UniCyrCode和UniLatCode。享元模式和C++模板

我的輕量級廠可以這樣做:

template <class T> 
class CodeFactory : public AbstractCodeFactory 
{ 
public: 
    CodeFactory(); 
    virtual ~CodeFactory(); 
    virtual Glyph* GetFlyweight(unsigned int code); 
    virtual Glyph* GetFlyweight(string letter); 
private: 
    // pool of flyweights (codes or letters) 
    map <unsigned int, Glyph*> my_code_map; 
    map <string, Glyph*> my_letter_map; 
}; 

這是可以做到這樣的:

template <class key, class T> 
class CodeFactory : public AbstractCodeFactory 
{ 
public: 
    CodeFactory(); 
    virtual ~CodeFactory(); 
    virtual Glyph* GetFlyweight(key code); 
private: 
    // pool of flyweights (codes or letters) 
    map <key, Glyph*> my_code_map; 
}; 

在第一個例子GCC連接器告訴我,有沒有字母(unsigned int類型)和xxxCode(字符串)構造函數。事實上,沒有任何和GCC是對的,但有沒有更好的方法來做到這一點,而不是定義這些構造函數?

在seccond ecample GCC編譯器告訴我,有上線

map <key, Glyph*>::iterator it; 
功能GetFlyweight的

錯誤。

實現這種輕量級模式的方法是什麼?

我需要使用它。 這是我目前的執行。

class AbstractCodeFactory 
{ 
public: 
    AbstractCodeFactory(); 
    virtual ~AbstractCodeFactory(); 
    virtual Glyph* GetFlyweight(unsigned int code) = 0; 
    virtual Glyph* GetFlyweight(string letter) = 0; 
}; 


template <class T> 
    class CodeFactory : public AbstractCodeFactory 
    { 
    public: 
     CodeFactory(); 
     virtual ~CodeFactory(); 
     virtual Glyph* GetFlyweight(unsigned int code); 
     virtual Glyph* GetFlyweight(string letter); 
    private: 
     // pool of flyweights (codes or letters) 
     map <unsigned int, Glyph*> my_code_map; 
     map <string, Glyph*> my_letter_map; 
    }; 


template <class T> 
    CodeFactory<T>::CodeFactory() 
    { 
     // TODO Auto-generated constructor stub 

    } 

template <class T> 
    CodeFactory<T>::~CodeFactory() 
    { 
     // TODO Auto-generated destructor stub 
     map <unsigned int, Glyph*>::iterator it; 
     map <string, Glyph*>::iterator l_it; 
     for (it = my_code_map.begin(); it != my_code_map.end(); ++it) 
     { 
      delete it->second; 
      it->second = NULL; 
      my_code_map.erase(it); 
     } 
     for (l_it = my_letter_map.begin(); l_it != my_letter_map.end(); ++l_it) 
     { 
      delete l_it->second; 
      l_it->second = NULL; 
      my_letter_map.erase(l_it); 
     } 
    } 

template <class T> 
    Glyph* CodeFactory<T>::GetFlyweight(unsigned int code) 
    { 
     map <unsigned int, Glyph*>::iterator it; 
     T *code_class = NULL; 
     if ((it = my_code_map.find(code)) == my_code_map.end()) 
     { 
      my_code_map.insert(pair <unsigned int, Glyph*> (code, code_class = new T(code))); 
      return code_class; 
     } 
     else return it->second; 
    } 

template <class T> 
    Glyph* CodeFactory<T>::GetFlyweight(string letter) 
    { 
     map <string, Glyph*>::iterator it; 
     T *letter_class = NULL; 
     if ((it = my_letter_map.find(letter)) == my_letter_map.end()) 
     { 
      my_letter_map.insert(pair <string, Glyph*> (letter, letter_class = new T(letter))); 
      return letter_class; 
     } 
     else return it->second; 
    } 
+1

你確實需要使用它,或者你只是想教育自己?如果前者,看看Boost.Flyweight。 – 2010-09-11 11:19:01

+1

我們需要實施以幫助您。 – tibur 2010-09-11 12:07:45

+1

「[...] GCC編譯器告訴我,該行存在錯誤[...]」 - 人們何時會學會僅僅發佈確切的錯誤消息? – 2010-09-13 07:25:06

回答

1

當你的輕量級的工廠只能生產中任一字母,YusciiCode,UniCyrCode或UniLatCode對象,我會去的第二個選項(指示鍵類型的第二模板參數

編譯器與聲明map <key, Glyph*>::iterator it;有關的問題是,編譯器無法確定map<key, Glyph*>::iterator是否指向某個類型或其他類型 這是因爲它取決於模板參數key,而且您可能具有map<>某個地方的成員iterator而不是是一種類型。
爲了幫助編譯器時,你必須指定期望map<ket, Glyph*>::iterator是指一個類型名:

typename map<key, Glyph*>::iterator it; 
+0

謝謝,我會盡量按照你的建議來實現它。 – 2010-09-14 12:20:30