您不能停用类(此处为 std::basic_string)的特定功能,因为它的接口清楚地(并且正式地)允许该操作。试图重载操作符只会把事情搞砸。
现在,你可以在另一个类中“包装”std::basic_string,使用私有继承或组合,然后使用公共接口作为 std::basic_string 部分的代理,但只有您希望使用的功能。
我建议先用 typedefs 替换你的字符串类型:
namespace myapp
{
typedef std::string String;
typedef std::wstring UTFString;
}
然后,一旦您的应用程序在将 std::string 和 std::wstring 替换为 myapp::String 和 myapp::UTFString(这些是示例名称)后编译正常,您就可以在某处定义包装类:
namespace myapp
{
/** std::basic_string with limited and controlled interface.
*/
template< class _Elem, class _Traits, class _Ax >
class limited_string
{
public:
typedef std::basic_string< _Elem , _Traits, _Ax > _String; // this is for easier writing
typedef limited_string< _Elem, _Traits, _Ax > _MyType; // this is for easier writing
private:
_String m_string; // here the real std::basic_string object that will do all the real work!
public:
// constructor proxies... (note that those ones are not complete, it should be exactly the same as the original std::basic_string
// see some STL docs to get the real interface to rewrite)
limited_string() : m_string {}
limited_string( const _MyType& l_string ) : m_string( l_string.m_string ) {}
limited_string( const _Elem* raw_string ) : m_string( raw_string ) {}
//... etc...
// operator proxies...
_MyType& operator= ( const _MyType& l_string )
{
m_string = l_string.m_string;
}
// etc...
// but we don't want the operator += with int values so we DON'T WRITE IT!
// other function proxies...
size_t size() const { return m_string.size(); } // simply forward the call to the real string!
// etc...you know what i mean...
// to work automatically with other STL algorithm and functions we add automatic conversion functions:
operator const _Elem*() const { return m_string.c_str(); }
// etc..
};
}
...然后,您只需替换这些行:
// instead of those lines...
//typedef std::string String;
//typedef std::wstring UTFString;
// use those ones
typedef limited_string< char, std::char_traits<char>, std::allocator<char> > String; // like std::string typedef
typedef limited_string< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > UTFString; // like std::wstring typedef
...你的例子会崩溃:
error C2676: binary '+=' : 'myapp::UTFString' does not define this operator or a conversion to a type acceptable to the predefined operator
error C2676: binary '+=' : 'myapp::String' does not define this operator or a conversion to a type acceptable to the predefined operator
这是我为证明这一点而编写的完整测试应用程序代码(在 vc9 上编译):
#include <string>
#include <iostream>
namespace myapp
{
/** std::basic_string with limited and controlled interface.
*/
template< class _Elem, class _Traits, class _Ax >
class limited_string
{
public:
typedef std::basic_string< _Elem , _Traits, _Ax > _String; // this is for easier writing
typedef limited_string< _Elem, _Traits, _Ax > _MyType; // this is for easier writing
private:
_String m_string; // here the real std::basic_string object that will do all the real work!
public:
// constructor proxies... (note that those ones are not complete, it should be exactly the same as the original std::basic_string
// see some STL docs to get the real interface to rewrite)
limited_string() : m_string {}
limited_string( const _MyType& l_string ) : m_string( l_string.m_string ) {}
limited_string( const _Elem* raw_string ) : m_string( raw_string ) {}
//... etc...
// operator proxies...
_MyType& operator= ( const _MyType& l_string )
{
m_string = l_string.m_string;
}
// etc...
// but we don't want the operator += with int values so we DON'T WRITE IT!
// other function proxies...
size_t size() const { return m_string.size(); } // simply forward the call to the real string!
// etc...you know what i mean...
// to work automatically with other STL algorithm and functions we add automatic conversion functions:
operator const _Elem*() const { return m_string.c_str(); }
// etc..
};
// instead of those lines...
//typedef std::string String;
//typedef std::wstring UTFString;
// use those ones
typedef limited_string< char, std::char_traits<char>, std::allocator<char> > String; // like std::string typedef
typedef limited_string< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > UTFString; // like std::wstring typedef
}
int main()
{
using namespace myapp;
int age = 27;
UTFString str = UTFString(L"User's age is: ");
str += age; // compilation error!
std::wcout << str << std::endl;
String str2 = String("User's age is: ");
str2 += age; // compilation error!
std::cout << str2 << std::endl;
std::cin.ignore();
return 0;
}
我认为它会彻底解决您的问题,但您必须包装所有功能。