2012-11-27 113 views
0

我正在寫一個'開啓'模式的班,很容易開關,然後我有點困惑。在超載的運營商=從另一個類複製,訪問私人T成員m_Mode被授予,爲什麼會發生這種情況?它是標準的,還是編譯器錯誤?班級參考資料授予訪問私人會員

template<class T> 
class CFixedMode 
{ 
private: 
    T m_Mode; 
public: 
    CFixedMode() 
    { 
     m_Mode = static_cast<T>(0); 
    } 
    ~CFixedMode(){} 
    void   SetMode(T mode); 
    void   SetNotMode(T mode); 
    BOOL   IsMode(T mode); 
    CFixedMode<T>&    operator=(const CFixedMode<T>& rFixedMode); 
}; 

template<class T>void CFixedMode<T>::SetMode(T mode) 
{ 
    m_Mode |= mode; 
} 
template<class T>void CFixedMode<T>::SetNotMode(T mode) 
{ 
    m_Mode &= (~mode); 
} 
template<class T>BOOL CFixedMode<T>::IsMode(T mode) 
{ 
    return ((m_Mode & mode) == mode) ? TRUE : FALSE; 
} 
template<class T>CFixedMode<T>& CFixedMode<T>::operator =(const CFixedMode<T>& rFixedMode) 
{ 
    if(typeid(m_Mode) == typeid(rFixedMode.m_Mode)) 
     m_Mode = rFixedMode.m_Mode; 
    return *this; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CFixedMode<DWORD> Mode; 
    DWORD rMode = 0x00000010; 
    Mode.SetMode(rMode); 

    CFixedMode<DWORD> Mode2; 
    Mode2 = Mode; 
    if(Mode2.IsMode(0x00000010)) 
    { 
     //cout << Mode2.m_Mode; //c2248 
     cout << "True" << endl; 
    } 

    typeid(Mode).before(typeid(CFixedMode<DWORD>)); 

    return 0; 
} 
+1

您的'operator ='只接受T的相同類型,這意味着它是相同的類,因此可以訪問私有成員。 – chris

+0

那麼整個'typeid'事情都不是必需的?但是,這是標準的權利? –

+2

正確,因爲您只接受參數的相同模板實例化,所以'typeid'比較應該始終爲真。 – chris

回答

1

私人手段,它是私有的的類,不實例類的。 Private用於隱藏實現細節,因此相同類型的對象可以訪問其他對象的私有成員是合理的。那些其他對象具有相同的實現,所以隱藏細節沒有意義。

順便說一句,您的運營商=應該檢查自我分配。 (或者,正如克里斯指出的,你可以使用複製和交換習慣用法。)而且,你不需要用typeid檢查類型。

+0

嗯,這實際上解釋了爲什麼有時會有'const'重載操作符 –

+0

或者您可以考慮執行復制交換。 – chris

+0

@ViniyoShouta不知道const如何直接進入這裏?當你希望能夠對const值或引用進行操作時,const與重載操作符一起使用。例如,'const Obj a = ...; Obj b = ...; Obj c = a + b;'如果沒有定義const運算符+,編譯器將不會編譯。 – Corbin