I've been trying to learn more about private inheritance and decided to create a string_t
class that inherits from std::basic_string
. I know a lot of you will tell me inheriting from STL classes is a bad idea and that it's better to just create global functions that accept references to instances of these classes if I want to extend their functionality. I agree, but like I said earlier, I'm trying to learn how to implement private inheritance.
This is what the class looks like so far:
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 ) );
}
};
I get the following errors:
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;
EBO
optimization apply (Empty Base Optimization), and sincestd::string
has data, it does not qualify. All the other "reasons" (like virtual redefinition) have other solutions (in this precise case, public inheritance + composition). Inheritance is a very strong relationship, notably in term of visibility, it's better than friendship, but not by much. And for this problem, you can perfectly add free-functions to extend an interface. – Matthieu M.string
's destructor is sufficient, there shouldn't be an issue. By the way, your code compiles for me. I also fleshed it out and tested it; everything should be fine. – Potatoswatter