[問題] template一問

看板C_and_CPP作者 (沒有不可能)時間14年前 (2011/11/10 17:52), 編輯推噓5(5029)
留言34則, 7人參與, 最新討論串8/9 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Visual C++ 2008 問題(Question): TEnMap與STL的Map操作類似 請問一下第二個class CItemInfoPool::AddItemInfo 裡面為何 可以直接這樣寫 pNewItemInfo->SetItemCode(strItemCode); 她是怎麼解析到T為CItemInfoBase? 另外我如果把<typename T> 代成其他類型,像int,這樣是不是就error了? //Source Code class CItemInfoBase { public: typedef TEnMap<CEnAString, CItemInfoBase*> ItemInfoMAP; typedef ItemInfoMAP::iterator ItemInfoMAP_ITER; typedef ItemInfoMAP::const_iterator ItemInfoMAP_CITER; typedef ItemInfoMAP::reverse_iterator ItemInfoMAP_RITER; typedef ItemInfoMAP::const_reverse_iterator ItemInfoMAP_CRITER; typedef ItemInfoMAP::value_type ItemInfoMAP_VTYPE; /* 中略 */ public: CItemInfoBase& operator = (const CItemInfoBase& info) { m_strItemCode = info.m_strItemCode; return *this; } public: void SetItemCode(const CEnAString& strItemCode){m_strItemCode=strItemCode;} const CEnAString& GetItemCode() const {return m_strItemCode;} protected: CEnAString m_strItemCode; }; //------------------------------------------------------------------------- class CItemInfoPool { public: /* 中略 */ template <typename T> T* AddItemInfo(const CEnAString& strItemCode, const T& ItemInfo) { CItemInfoBase::ItemInfoMAP_ITER found=m_mapItemInfos.find(strItemCode); if (found != m_mapItemInfos.end()) return (T*)found->second; T* pNewItemInfo = new T; *pNewItemInfo = ItemInfo; pNewItemInfo->SetItemCode(strItemCode); m_mapItemInfos[strItemCode] = pNewItemInfo; m_iNumOfItemInfos++; return pNewItemInfo; } const CItemInfoBase::ItemInfoMAP& GetItemInfos() const{return m_mapItemInfos;} protected: CItemInfoBase::ItemInfoMAP m_mapItemInfos; }; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.120.1.136 ※ 編輯: gogohata 來自: 59.120.1.136 (11/10 17:53) ※ 編輯: gogohata 來自: 59.120.1.136 (11/10 17:54)

11/10 18:01, , 1F
所以那個template function只能餵CItemInfoBase或它的
11/10 18:01, 1F

11/10 18:02, , 2F
衍生類別 亂餵會error沒錯
11/10 18:02, 2F

11/10 18:19, , 3F
我想問的是為什她可以直接把pointer指到SetItemCode()?
11/10 18:19, 3F

11/10 18:30, , 4F
編譯時 compiler會根據使用到此template的地方代入指定
11/10 18:30, 4F

11/10 18:31, , 5F
的typename 如果compiler發現你餵了錯誤的typename給這
11/10 18:31, 5F

11/10 18:32, , 6F
個template function 就會compile error
11/10 18:32, 6F

11/10 18:32, , 7F
而他當然可以指到SetItemCode() 只要compiler看到你餵
11/10 18:32, 7F

11/10 18:33, , 8F
的typename有SetItemCode()就好
11/10 18:33, 8F

11/10 18:33, , 9F
甚至, 如果根本沒有其它code用到此template, 那你還可
11/10 18:33, 9F

11/10 18:34, , 10F
以指到任何UnknownFunction() (印象中是可以啦...)
11/10 18:34, 10F

11/10 20:04, , 11F
恐怖的命名
11/10 20:04, 11F

11/10 21:51, , 12F
可以是CopyAssignable卻不是CopyConstructable...
11/10 21:51, 12F

11/10 23:10, , 13F
不懂樓上所言@@
11/10 23:10, 13F

11/11 01:36, , 14F
意思是說你有 operator = 卻沒有 copy constructor
11/11 01:36, 14F

11/11 01:36, , 15F
不過那就是題外話了
11/11 01:36, 15F

11/11 11:12, , 16F
是只說在operator = 裡面還要加上建構式的意思嗎?
11/11 11:12, 16F

11/11 11:23, , 17F
你要做=裡面就是再做copy,所以你只提供=沒有copy
11/11 11:23, 17F

11/11 11:24, , 18F
會有問題出現
11/11 11:24, 18F

11/11 12:00, , 19F
其實可以只提供copy assign operator
11/11 12:00, 19F

11/11 12:00, , 20F
而不提供copy constructor啦
11/11 12:00, 20F

11/11 12:01, , 21F
個人覺得這比較算是一種風格或優良習慣的問題
11/11 12:01, 21F

11/11 12:23, , 22F
我比較想知道會造成甚麼樣的問題出現@@
11/11 12:23, 22F

11/11 12:57, , 23F
如果你沒有定義的話,它會使用預設的copy,就要看
11/11 12:57, 23F

11/11 12:58, , 24F
有沒有符合你的需求了
11/11 12:58, 24F

11/11 13:33, , 25F
通常有指標的操作時,記得寫copy ctor.
11/11 13:33, 25F

11/11 14:23, , 26F
因為當你寫了 copy assignment 的時候
11/11 14:23, 26F

11/11 14:24, , 27F
表示預設的 member-wise copy 並不是你想要的行為
11/11 14:24, 27F

11/11 14:24, , 28F
那很明顯預設的 copy ctor 也不會是你想要的行為
11/11 14:24, 28F

11/11 14:24, , 29F
所以你幾乎一定要改掉預設的 copy ctor
11/11 14:24, 29F

11/11 14:25, , 30F
我還沒看過哪個class有copy assigment卻沒有copy ctor
11/11 14:25, 30F

11/11 15:04, , 31F
如果有自信絕對不會被call到copy ctor的話就可以不做(?
11/11 15:04, 31F

11/11 15:04, , 32F
不過事實上copy ctor會在很多隱性的地方被呼叫 如STL
11/11 15:04, 32F

11/11 15:37, , 33F
基本上copy assigment和copy ctor是有很多隱性呼叫
11/11 15:37, 33F

11/11 15:37, , 34F
的機會
11/11 15:37, 34F
文章代碼(AID): #1EkvxA01 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1EkvxA01 (C_and_CPP)