2505 / 1480 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
1

Вывод данных и перегрузка операторов.

07.04.2012, 00:08. Показов 1065. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый вечер, объясните пожалуйста что я не так делаю.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
class A{
public:
       int a;
       A& operator++(){         
          ++a;
          return *this;
       }
};
 
int main(void) {
    A elem={1};
    cout<<elem.a<<(++elem).a<<(++elem).a<<elem.a;
    //system("PAUSE");
    return 0;
}
Выводиться 3333. Почему не 1233? И почему если я сделаю так
C++ (Qt)
1
2
cout<<elem.a;
cout<<(++elem).a<<(++elem).a<<elem.a;
то уже будет 1333?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.04.2012, 00:08
Ответы с готовыми решениями:

Потоковый ввод/вывод в файл(перегрузка операторов >> <<)
Доброго дня. Разбираю потоковый ввод/вывод данных в файл, с помощью перегрузки операторов сдвига...

Что такое "перегрузка операторов"? Каковы принципы работы перегруженных операторов и назначение указателя this
Добрый день . Помогите понять принцип работы перегрузки операторов. объясните пожалуйста в...

Вывод данных, перегрузка операций
Задание: Описать класс товар, содержащий следующие закрытые поля: o Название товара o Название...

Перегрузка операторов
У меня есть такая программа. :cry: Мне нужно обеспечить реализацию перегрузки арифметических і...

12
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.04.2012, 00:18 2
Какова цель? Я если честно вообще не могу понять половины из написанного кода
0
2505 / 1480 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
07.04.2012, 00:21  [ТС] 3
Цель - изучение языка, это я попробовала поперезагружать операторы.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.04.2012, 00:24 4
Ну тогда думаю имелось ввиду вот это
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
 
class A {
public:
  A( int b ) : a( b ) {
 
  };
       int a;
       A& operator++(){
          ++a;
          return *this;
       }
};
 
int main(void) {
    A elem(1);
 
    cout << elem.a;
 
    ++elem;
    cout << elem.a;
 
    ++elem;
    cout << elem.a;
    //system("PAUSE");
    return 0;
}
0
2505 / 1480 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
07.04.2012, 00:28  [ТС] 5
Спасибо, но Вы не совсем меня поняли. Меня интересует не как заствить работать, а почему не работает вот так
cout<<elem.a<<(++elem).a<<(++elem).a<<elem.a;
И что меняется при разделении на несколько cout.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.04.2012, 00:35 6
На сколько знаю, очередность операций в потоке cout не определена, и зависит от компилятора. У меня например выводит 3321. Поэтому, думаю, вычисления лучше производить отдельным оператором, а потом уже выводить данные.
0
2505 / 1480 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
07.04.2012, 00:49  [ТС] 7
Ну вот например же при
C++ (Qt)
1
2
int a=1;
cout<<a<<++a<<++a<<a;
будет выведено 1233, всегда. Никогда не слышала про неопределенность очередности вывода. Может тут как-то с буфером связано?
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.04.2012, 01:00 8
Цитата Сообщение от Грымзик Посмотреть сообщение
Может тут как-то с буфером связано?
Скорее с реализацией отдельного компилятора

Добавлено через 6 минут
Я же с вашим кодом получаю
main.cpp:19:33: error: operation on 'a' may be undefined [-Werror=sequence-point]
То есть компилятор говорит что операция над a может быть не определена. Так как переменная модифицируется два раза в потоке. Вот думаю будет интересно почитать тык
2
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
07.04.2012, 01:36 9
Toshkarik, дело не в потоке, поток - просто абстракция, неизвестная компилятору. Дело в точках следования, по сути, такое выражении можно сравнить с
C++
1
i = i++ + ++i;
Это очень любят давать на собеседованиях.
1
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
07.04.2012, 02:40 10
silent_1991, да, я это понимаю. Я просто говорил про данный конкретный случай. На сколько я понимаю, переменная должна модифицироваться ровно один раз в промежутке от одной точки следования до другой. В данном случае от одной ; до другой ;
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
07.04.2012, 03:08 11
Цитата Сообщение от Toshkarik Посмотреть сообщение
переменная должна модифицироваться ровно один раз в промежутке от одной точки следования до другой
Не должна. Просто переход через точку следования гарантирует, что все эффекты от действий, произведённых до этой точки следования, уже вступили в силу. Проблема здесь в том, что стандарт не определяет, как должен вычисляться инкремент (а значит, что когда он реально вычислится, зависит от самых разных вещей, начиная с внутреннего представления программы в компиляторе и заканчивая вспышками на солнце).
В данном конкретном случае могу предположить, что компилятор воспринял выражение
C++
1
cout<<elem.a<<(++elem).a<<(++elem).a<<elem.a;
как
C++
1
2
3
4
5
6
7
8
//(++elem).a;
t2 = elem.operator++().operator++().a;
// Скорее всего, в данном случае точкой следования является не очередной
// каскадный вызов operator<<, а ; в конце всего выражения; таким образом,
// компилятор вправе вычислять аргументы как ему вздумается, и он просто
// вычислил всё один раз и сохранил во временной переменной (возможно, свою
// роль сыграл и оптимизатор)
cout.operator<<(t2).operator<<(t2).operator<<(t2).operator<<(t2);
отчего и наблюдается данный эффект.

Добавлено через 12 минут
Я ошибся. На самом деле код будет воспринят как
C++
1
operator<<(operator<<(operator<<(operator<<(cout, elem.a), elem.operator++().a), elem.operator++().a), elem.a);
и тогда всё встаёт на свои места, порядок вычисления аргументов при вызове функции не определён стандартом, известно лишь, что к моменту вызова все побочный эффекты вступят в силу (т.е. момент вызова функции после вычисления всех аргументов - точка следования). Вот мы и получаем неопределённый порядок вычисления аргументов.
2
2505 / 1480 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
07.04.2012, 21:57  [ТС] 12
Спасибо большое! Но все-таки поражаюсь, ведь для ++i код будет воспринят также. Почему тогда уже другой порядок вычисления аргументов Теперь буду остерегаться делать то, что раньше для меня было абсолютно естественным.
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
07.04.2012, 23:17 13
Грымзик, в одном случае вызов пользовательского метода (operator++), в другом - выполнение стандартной операции. Эти две вещи обрабатываются по-разному (пользовательские операции обрабатываются как функции).
1
07.04.2012, 23:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.04.2012, 23:17
Помогаю со студенческими работами здесь

Перегрузка операторов
Помогите, пожалуйста, решить задачу При создании собственных типов данных с помощью классов...

Перегрузка операторов
Привет, не подскажите, почему у меня тут не работает правильно += оператор. #include &lt;iostream&gt;...

Перегрузка операторов
Написал такой код: class CVector: def __init__(self, x_, y_): self.m_x = x_ self.m_y...

Перегрузка операторов <<, >>
у меня есть класс, к примеру template &lt;typename type&gt; class ls { private: type val;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru