Большинство проблем уже решены. У меня просто есть предложение, которое не было написано выше:
Используйте форму свободной функции оператора сравнения вместо функции-члена:
bool operator == (MyString const &, MyString const &);
Вам нужно будет объявить его своим другом, если это зависит от личных данных / участников, но вы получите симметрию для вызывающих. Предполагая, что (как и в случае с std :: string) у вас есть неявное преобразование, определенное из const char *
в вашу строку, реализация функции-члена == не является симметричной. Функции-члены требуют, чтобы левая часть была требуемого типа. Компилятор не будет выполнять преобразования в левой части сравнения:
// assumes MyString( const char* ) is defined and not explicit
// operator== defined as member function
const char* literal = "hola";
MyString str( "hola" );
if ( str == literal ) {} // correct
if ( literal == str ) {} // compilation error
Если вы реализуете в качестве функции-члена, в первом тесте компилятор создаст безымянную строку MyString и вызовет оператор преобразования. Во второй проверке компилятору не разрешается преобразовывать literal
в MyString, поэтому он никогда не найдет вашу реализацию operator==
.
Если вы предоставите сравнение как бесплатную функцию, то компилятор применит одинаковые правила преобразования с обеих сторон ==, а код скомпилируется и будет работать правильно.
В общем, то же самое относится и к остальным операторам (исключая operator [] и operator =, которые должны быть реализованы как функции-члены). Использование бесплатной версии функции обеспечивает симметрию.