【问题标题】:Class reference grants access to private member类引用授予对私有成员的访问权限
【发布时间】:2012-11-27 06:29:22
【问题描述】:

我正在写一个轻松“打开”模式的课程,然后我有点困惑。在重载的 operator= 上从另一个类复制,访问私有 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;
}

【问题讨论】:

  • 你的operator= 只接受相同类型的 T,这意味着它是同一个类,因此可以访问私有成员。
  • 那么整个typeid 的事情甚至没有必要?但那是标准的吧?
  • 正确,因为您只接受参数的相同模板实例化,typeid 比较应该始终为真。

标签: c++ templates private-members


【解决方案1】:

Private 意味着它是私有的 class,而不是类的 instances。私有用于隐藏实现细节,因此相同类型的对象可以访问其他对象的私有成员是有意义的。那些其他对象具有相同的实现,因此隐藏细节没有意义。

顺便说一下,您的 operator= 应该检查自分配。 (或者,正如 Chris 指出的那样,您可以使用复制和交换习语。)而且,您不需要使用 typeid 检查类型。

【讨论】:

  • 嗯,这实际上解释了为什么有时const 用于重载运算符
  • @ViniyoShouta 哦,我以为你的意思是实际的重载是 const,而不是 rhs 参数。是的,rhs 参数应始终为 const。如果 operator= 可以改变右手边,那将是一个奇怪的、奇怪的副作用。我相信 const 实际上需要符合标准(虽然不是 100% 肯定)。
  • 是的,经过测试,它确实具有参考价值。有点武器诶。
  • @ViniyoShouta 有趣。我也刚刚检查过,我相信标准并不要求它是 const。我认为这是有道理的,因为 C++ 喜欢让你做任何可能的事情。我想这个类的消费者理论上应该负责知道它会改变 rhs(作者将负责做出这个奇怪的决定,并希望记录下它的地狱)。
  • @ViniyoShouta 关于 const 引用参数的另一件事:如果它是一个非常量引用,您将无法在 RHS 上使用临时值。
猜你喜欢
  • 2013-10-16
  • 2011-03-07
  • 2014-08-09
  • 2012-03-15
  • 2012-09-23
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多