Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.11.2010, 12:10   #1
AJlekceu
Пользователь
 
Регистрация: 20.11.2010
Сообщений: 16
Вопрос Является ли "operator+" lvalue?

Уважаемые форумчане! В процессе активного экспериментирования в среде Borland C++ Builder (6.0) заступорился на следующей вещи.
Есть библиотечный класс AnsiString, у него есть метод "operator+", его прототип таков:
Код:
AnsiString __fastcall operator +(const AnsiString&) const
Совершенно непонятным для меня является нижеизложенный факт.
Есть фрагмент кода:
Код:
AnsiString s1, s2;
s1 + s2 = "OLOLO";
Данный код не делает ничего полезного, и это не важно.
Ошибка "Lvalue required" не выскакивает, программа компилится! Словно прототип выглядит так:
Код:
AnsiString& __fastcall operator +(const AnsiString&) const
Но он не выглядит так. Так в чём же дело?
Можно было бы мне, конечно, отследить ход работы процессора, но я не являюсь большим спецом по ассемблеру

Последний раз редактировалось AJlekceu; 25.11.2010 в 12:34.
AJlekceu вне форума Ответить с цитированием
Старый 25.11.2010, 12:20   #2
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Совершенно верно. Никакой ошибки не будет так-как operanor+, это перегруженный оператор. В данном случае он выполняет функцию не сложения (т.е. буквы строк не складываются между собой, как бы в столбик), а канкотенации, т.е. слияния строк. Если в функцию добавить знак амперсанда, то будет происходить сложение в столбик. причём сложение будет не арифметическим, а логическим.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 25.11.2010, 12:32   #3
AJlekceu
Пользователь
 
Регистрация: 20.11.2010
Сообщений: 16
По умолчанию

Ясно, что конкатенации =) Я не перегружал оператор+, и поэтому, как я думал, должен происходить вызов библиотечного метода
Код:
AnsiString __fastcall AnsiString::operator+(const AnsiString&) const
Этот метод должен вернуть значение (а не ссылку) результата конкатенации s1 и s2. В результате слева от знака "=" окажется значение, а не переменная (или ссылка), что должно привести к ошибке "Lvalue required" (это все равно, что написать
Код:
int i;
100500 = i;
)
И, как ни странно, никакой ошибки с++ не выдаёт.
AJlekceu вне форума Ответить с цитированием
Старый 25.11.2010, 12:51   #4
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от AJlekceu Посмотреть сообщение
Ясно, что конкатенации =) Я не перегружал оператор+, и поэтому, как я думал, должен происходить вызов библиотечного метода
Это не вы его перегружаете, а сам оператор является перегруженным, т.е. иными словами переопределённым самой функцией. Это значит, что значение знака "+" понимается не в общепринятом понимании.
Когда вы обращаетесь к библиотеке, производя операцию A + B (AnsiString), автоматически вызывается operator+ и всё происходит само собой.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 25.11.2010, 13:14   #5
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

А что такого в том, что объект возвращается не по ссылке?
Код:
s1 + s2 = "OLOLO";
Результат s1 + s2 есть временный объект типа AnsiString, который вполне себе является lvalue. Другое дело, что этот временный объект потом нигде не используется.
Попробуйте, например, на событие кнопки кинуть такой код:
Код:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString s1, s2, s3;
s2 = "!";
s3 = "+";
s1 = (s2 + s3 = "^_^");
Form1 -> Caption = s1;
}
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 25.11.2010, 13:31   #6
AJlekceu
Пользователь
 
Регистрация: 20.11.2010
Сообщений: 16
По умолчанию

Гром, в этом и дело! =) Значит, это что-то временное. Но почему тогда я сам, когда напишу
Код:
class TA {
   int o;
   TA& operator= (TA op2);
   TA operator+ (TA op2);
};

TA& TA::operator= (TA op2) {
   o = op2.o * 100500;
   return *this;
}

TA TA::operator+ (TA op2) {
   TA ret;
   ret.o = o + op2.o + 100;
   return ret;
}

...

   TA c1, c2, c3;
   c1 + c2 = c3;
выдаётся ошибка "Lvalue required"?

Последний раз редактировалось AJlekceu; 25.11.2010 в 13:34.
AJlekceu вне форума Ответить с цитированием
Старый 25.11.2010, 13:33   #7
AJlekceu
Пользователь
 
Регистрация: 20.11.2010
Сообщений: 16
По умолчанию

Упс, прошу прощения, никакой ошибки нет)
AJlekceu вне форума Ответить с цитированием
Старый 25.11.2010, 13:59   #8
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Цитата:
Сообщение от AJlekceu
Этот метод должен вернуть значение (а не ссылку) результата конкатенации s1 и s2. В результате слева от знака "=" окажется значение, а не переменная (или ссылка), что должно привести к ошибке "Lvalue required"
Не должно.

Цитата:
Сообщение от AJlekceu
(это все равно, что написать
А вот как раз далеко не все равно.

Цитата:
Сообщение от Гром
Результат s1 + s2 есть временный объект типа AnsiString, который вполне себе является lvalue.
Не является. Это rvalue.

Автор, в С++ lvalue это не просто "та штука, которая может стоять слева от оператора присваивания". Советую все-таки поглядывать в стандарт - там ясно написано, что для rvalue-классов можно вызывать функции-члены, поэтому некоторые rvalue вполне могут находиться слева от =.

Цитата:
Сообщение от C++03
Every expression is either an lvalue or an rvalue. An lvalue refers to an object or function. Some rvalue expressions—those of class or cv-qualified class type—also refer to objects.
Expressions such as invocations of constructors and of functions that return a class type refer to objects, and the implementation can invoke a member function upon such objects, but the expressions are not lvalues.
still_alive вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите что обозначает "диск D:/ не является приложением win32." Ospa Windows 19 05.06.2011 21:02
ошибкa "missing operator or semicolon" Дим@@ Помощь студентам 3 11.11.2010 15:14
Qt, как использовать "operator==" lecume Помощь студентам 0 05.10.2010 18:00
ошибка expected init-declarator before "operator" Tev Общие вопросы C/C++ 2 13.11.2008 22:31
Является ли Assembler для вас "лесом дремучим"? Delpher Свободное общение 9 14.12.2007 11:32