Здравствуйте, MikelSV, Вы писали:
MSV>Кода много, не знаю, что именно показывать.
MSV>В данном случае единственный вариант реализации operator+ может быть:
MSV>HLString& operator+(const MString& string){...}
Это далеко не единственный вариант ошибочной реализации operator+ и подобных ему операторов.
MSV>Это строковый класс, он прибавляет текст у уже записанному в нем.
Суть operator+ в создании нового объекта посредством объединения двух имеющихся (конкатенации).
Возьмем например:
a = 2 + 2
Было бы маразмом полагать, что первое слагаемое после этого станет равным 4. Это две константы. Так какого, простите, перепуга вы ожидаете другого поведения с вашими строками? Если вы пишете
some_class1(5) + some_class2(4)
— это
тоже самое. Поэтому,
во-первых, operator+, operator- и иже с ними
никогда не должны возвращать ссылку, если только вы не хотите устроить себе грабли на ровном месте.
во-вторых, семантика описанного вами оператора соответствует operator+=, вот он, да, он возвращает ссылку, только это совсем другая песня.
в-третьих, функция operator+ должна быть свободной. Во избежание неожиданных эксцессов в вариантах с перестановкой слагаемых.
Итого:
my_string operator+(my_string const & a, other_string const & b) // const, ибо мы не изменяем слагаемые, мы формируем из них результат
{
my_string result(a.size() + b.size());
// операции по объединению строк
return result; // в результате my_string, ибо мы прибавляем к ней
}
other_string operator+(other_string const & a, my_string const & b) // const, ибо мы не изменяем слагаемые, мы формируем из них результат
{
other_string result(a.size() + b.size());
// операции по объединению строк
return result; // в результате other_string, ибо мы прибавляем к ней
}
other_string const & res = other_string("bla-bla") + my_string("bla-bla"); // будет работать
other_string res = other_string("bla-bla") + my_string("bla-bla"); // будет работать
my_string const & res = my_string("bla-bla") + other_string("bla-bla"); // ок
my_string res = my_string("bla-bla") + other_string("bla-bla"); // ок
my_string & res = my_string("bla-bla") + other_string("bla-bla"); // бамс, ошибка!
Я заметил, что вы пропускаете мимо ушей все что я пишу. Поэтому советую вам обратиться в главу 11 — Перегрузка Операторов, русского издания книги Б. Страуструпа "Язык программирование С++. 3е издание", для вдумчивого чтения и подтверждения всего, что я выше написал.
MSV>Собственно тут все просто, класс собирает текст в строку и возвращает ее через operator MString().
Вы правы, все очень просто. Можно например посмотреть реализацию такого же механизма в библиотеке QT. Добавлю, что если придерживаться правил, которые я описал выше оператор приведения вам и вовсе не понадобится.
MSV>Кстати этот код работает:
MSV>Drawn((HLString()+"Uncnown command '"+comm+"'\r\n\r\n").operator MString());
MSV>Но я за то, чтобы компилятор сам догадывался о типах и не нужно было дописывать .operator MString().
Теперь к вашим баранам, откройте для себя mutable:
class MString;
class HLString
{
public:
HLString()
{}
HLString(char const * str)
: buf_(str)
{}
HLString const & add(char const * str) const
{
buf_ += str;
return *this;
}
HLString const & add(HLString const & str) const
{
buf_ += str.data();
return *this;
}
std::string const & data() const
{
return buf_;
}
HLString const & add(MString const & str) const;
private:
// для буфера использовал стандартную строку, здесь показана только суть
mutable std::string buf_; // mutable позволит менять данные в константных объектах
};
class MString
{
public:
MString()
{}
MString(char const * str)
: buf_(str)
{}
MString const & add(char const * str) const
{
buf_ += str;
return *this;
}
MString const & add(MString const & str) const
{
buf_ += str.data();
return *this;
}
std::string const & data() const
{
return buf_;
}
MString const & add(HLString const & str) const;
private:
// для буфера использовал стандартную строку, здесь показана только суть
mutable std::string buf_; // mutable позволит менять данные в константных объектах
};
MString const & MString::add(HLString const & str) const
{
buf_ += str.data();
return *this;
}
HLString const & HLString::add(MString const & str) const
{
buf_ += str.data();
return *this;
}
void Drawn(MString const & a)
{
std::cout << a.data() << std::endl;
}
int main()
{
HLString comm("test");
Drawn(MString().add("Unknown command '").add(comm).add("'\r\n\r\n"));
return 0;
}
MSV>Варианты для гцц также мучил в студии. Все нормально понимаются. Жесткое следование стандартам — зло.
Зло — это нарушение стандартов студией. Если бы язык был в ней правильно реализован с самого начала, то всего этого бардака не было бы.
Ведь все это сделано не просто так, а потому что иначе —
нелогично. Пример с оператором+ ясно это показывает.