我一直在尝试了解有关私有(private)继承的更多信息,并决定创建一个从string_t继承的std::basic_string类。我知道很多人都会告诉我从STL类继承是一个坏主意,如果我想扩展它们的功能,最好创建全局函数以接受对这些类实例的引用。我同意,但是就像我之前说的,我正在尝试学习如何实现私有(private)继承。

到目前为止,这是该类的样子:

class string_t :
#if defined(UNICODE) || defined(_UNICODE)
  private std::basic_string<wchar_t>
#else
  private std::basic_string<char>
#endif
{
public:
  string_t() : basic_string<value_type>() {}

  string_t( const basic_string<value_type>& str )
    : basic_string<value_type>( str ) {}

  virtual ~string_t() {}

  using std::basic_string<value_type>::operator=; /* Line causing error */

  std::vector<string_t> split( const string_t& delims )
  {
    std::vector<string_t> tokens;

    tokens.push_back( substr( 0, npos ) );
  }
};

我收到以下错误:
1>c:\program files\microsoft visual studio 9.0\vc\include\xutility(3133) : error C2243: 'type cast' : conversion from 'const string_t *' to 'const std::basic_string &' exists, but is inaccessible
1>        with
1>        [
1>            _Elem=wchar_t,
1>            _Traits=std::char_traits,
1>            _Ax=std::allocator
1>        ]

1>        c:\program files\microsoft visual studio 9.0\vc\include\xutility(3161) : see reference to function template instantiation 'void std::_Fill(_FwdIt,_FwdIt,const _Ty &)' being compiled
1>        with
1>        [
1>            _Ty=string_t,
1>            _FwdIt=string_t *
1>        ]

1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1229) : see reference to function template instantiation 'void std::fill(_FwdIt,_FwdIt,const _Ty &)' being compiled
1>        with
1>        [
1>            _Ty=string_t,
1>            _FwdIt=string_t *
1>        ]

1>        c:\program files\microsoft visual studio 9.0\vc\include\vector(1158) : while compiling class template member function 'void std::vector::_Insert_n(std::_Vector_const_iterator,unsigned int,const _Ty &)'
1>        with
1>        [
1>            _Ty=string_t,
1>            _Alloc=std::allocator
1>        ]

1>        c:\work\c++\string_t\string_t.h(658) : see reference to class template instantiation 'std::vector' being compiled
1>        with
1>        [
1>            _Ty=string_t
1>        ]

The line number (658) in the last error points to the opening brace of the split() function definition. I can get rid of the error if I comment out the using std::basic_string<value_type>::operator=; line. As I understand it, the using keyword specifies that the assignment operator is being brought from private to public scope within string_t.

Why am I getting this error and how can I fix it?

Also, my string_t class doesn't contain a single data member of it's own, much less any dynamically allocated members. So if I don't create a destructor for this class doesn't that mean that if someone were to delete an instance of string_t using a base class pointer the base class destructor would be called?

The following code throws an exception when I have a destructor defined for string_t but works when I comment out the destructor when compiled with VS2008.

basic_string<wchar_t> *p = new string_t( L"Test" );
delete p;

最佳答案

您的默认构造函数不应是显式的。我认为明确可能是它也无法将std::string转换为string_t的原因,但是您从代码段:vP中删除了该构造函数。

该程序可以在GCC 4.2上编译并正常运行:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class string_t :
#if defined(UNICODE) || defined(_UNICODE)
  private std::basic_string<wchar_t>
#else
  private std::basic_string<char>
#endif
{
public:
  string_t() : basic_string<value_type>() {}

  string_t( const basic_string<value_type>& str )
    : basic_string<value_type>( str ) {}

  virtual ~string_t() {}

  using std::basic_string<value_type>::operator=; /* Line causing error */

  std::vector<string_t> split( const string_t& delims )
  {
    std::vector<string_t> tokens;

    for ( size_t pen = 0, next = 0; next != npos; pen = next + 1 ) {
        next = find_first_of( delims, pen );
        if ( pen != next ) tokens.push_back( substr( pen, next - pen ) );
    }
    return tokens;
  }

  template<class os>
  friend os &operator<<(os &, string_t const&);
};

template< class os_t >
os_t &operator<<( os_t &os, string_t const &str ) {
        return os << static_cast< string >(str);
}

int main( int argc, char ** argv ) {
        vector<string_t> mytoks = string_t( argv[1] ).split( string( "_" ) );

        for ( vector<string_t>::iterator it = mytoks.begin(); it != mytoks.end(); ++ it ) {
                cerr << * it << endl;
        }
        return 0;
}

关于c++ - 从std::basic_string的私有(private)继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2025795/

10-14 15:14
查看更多