2012-11-27 65 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