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

时间:2015-05-18 08:10:27

标签: c++ constructor iterator const implicit-conversion

我正在编写一个UTF-8字符串类,它是两个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:\xxx\main.cpp 20

声明这些复制构造函数可以解决问题。

会发生什么?编译器是否将Utf8String::ConstIter i = sStr.Begin()优化为Utf8String::ConstIter i( sStr.Begin() )或进行其他隐式优化?

感谢您的帮助。 :)

编辑:使用VS2005而不使用C ++ 11.

1 个答案:

答案 0 :(得分:3)

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

相关问题