"for"循环中使用的复制构造函数,但在哪里?

Copy constructor used in a "for" loop, but where?

本文关键字:构造函数 在哪里 复制 for 循环      更新时间:2023-10-16

我正在写一个UTF-8字符串类,它是两个const和非const迭代器类。我遇到了一个const问题。下面是这些类:

class Utf8String
{
public:
   class ConstIter;
   class Iter
   {
      friend class ConstIter;
   private:
      Iter();
   private:
      Utf8String * m_pStr;
      utf8::iterator< char * > m_oIter;
   public:
      Iter( const Iter & );
      inline explicit Iter( Utf8String * pStr )
       : m_pStr( pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }
      inline Iter & operator = ( const Iter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< char * >(
            m_pStr->m_sBuf,
            m_pStr->m_sBuf,
            m_pStr->m_sBuf + m_pStr->m_nSize );
         return *this;
      }
      inline operator const char * () const
      {
         return m_oIter.base();
      }
      inline uchar32_t operator * () const
      {
         return *m_oIter;
      }
      inline Iter & operator ++ ()
      {
         ++m_oIter;
         return *this;
      }
      inline Iter & operator -- ()
      {
         --m_oIter;
         return *this;
      }
      inline bool operator == ( const Iter & oIter )
      {
         return m_oIter == oIter.m_oIter;
      }
      inline bool operator != ( const Iter & oIter )
      {
         return m_oIter != oIter.m_oIter;
      }
   };
   class ConstIter
   {
   private:
      ConstIter();
   private:
      const Utf8String * m_pStr;
      utf8::iterator< const char * > m_oIter;
   public:
      ConstIter( const ConstIter & );
      inline ConstIter( const Iter & oIter )
       : m_pStr( oIter.m_pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }
      inline ConstIter( const Utf8String * pStr )
       : m_pStr( pStr )
       , m_oIter( m_pStr->m_sBuf, m_pStr->m_sBuf, m_pStr->m_sBuf + m_pStr->m_nSize )
      { }
      inline operator const char * () const
      {
         return m_oIter.base();
      }
      inline ConstIter & operator = ( const ConstIter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< const char * >(
            oIter.m_pStr->m_sBuf,
            oIter.m_pStr->m_sBuf,
            oIter.m_pStr->m_sBuf + oIter.m_pStr->m_nSize );
         return *this;
      }
      inline ConstIter & operator = ( const Iter & oIter )
      {
         m_pStr = oIter.m_pStr;
         m_oIter = utf8::iterator< const char * >(
            m_pStr->m_sBuf,
            m_pStr->m_sBuf,
            m_pStr->m_sBuf + m_pStr->m_nSize );
         return *this;
      }
      inline uchar32_t operator * () const
      {
         return *m_oIter;
      }
      inline ConstIter & operator ++ ()
      {
         ++m_oIter;
         return *this;
      }
      inline ConstIter & operator -- ()
      {
         --m_oIter;
         return *this;
      }
      inline bool operator == ( const ConstIter & oIter )
      {
         return m_oIter == oIter.m_oIter;
      }
      inline bool operator != ( const ConstIter & oIter )
      {
         return m_oIter != oIter.m_oIter;
      }
   };
   // More stuff
};

我使用如下:

   Utf8String sStr = "not const";
   for( Utf8String::Iter i = sStr.Begin(); i != sStr.End(); ++i )
   {
   }
   // 2) Iterating over a const UTF-8 string :
   const Utf8String sConstStr = "const";
   for( Utf8String::ConstIter i = sConstStr.Begin(); i != sConstStr.End(); ++i )
   {
   }
   // 3) Const interators can also iterate over a non-const string :
   for( Utf8String::ConstIter i = sStr.Begin(); i != sStr.End(); ++i )
   {
   }
问题是,如果迭代器类的复制构造函数没有声明为public,尽管没有显式使用复制构造函数,我还是会得到以下错误:
Error   1   error C2248: 'core::Utf8String::Iter::Iter' : cannot access private member declared in class 'core::Utf8String::Iter'   c:xxxmain.cpp 20

将这些复制构造函数声明为public就解决了问题。

发生了什么?编译器是将Utf8String::ConstIter i = sStr.Begin()优化为Utf8String::ConstIter i( sStr.Begin() )还是做其他隐式优化?

谢谢你的帮助。:)

编辑:使用VS2005而不是c++ 11.

Utf8String::ConstIter i = sStr.Begin();是一个声明和一个初始化。它是不是赋值。这个初始化是使用复制构造函数完成的。