Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 54, средняя оценка - 4.83
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
#1

Перегрузка operator<< - C++

17.02.2011, 00:10. Просмотров 6735. Ответов 40
Метки нет (Все метки)

Доброе время суток.

Есть очередная задачка - перегрузить оператор вывода таким образом:

Есть три объекта разных классов - А а, В в, С с;

Нужно, чтобы при записи а << b << c; изменялось значение некоторых членов всех трех классов, ну грубо говоря, пусть там есть по одному члену типа float и пусть при такой записи вывода произойдет нечто вроде
b.f+=0.2*c.f;
a.f+=0.8*c.f;

А при любой другой записи - (b<<c<<a, c<<b<<a, b<<a<<c, a<<b<<a) - пусть проводится просто вывод каких-нибудь членов класса, не суть важно. Или даже ошибка за неправильный порядок членов в выводе.

Можно ли это вообще сделать, а если нельзя, то что требуется от этих трех объектов?

Точно известно, что речь про перегрузку вывода, а не перегрузку сдвига.
С перегрузкой я знаком, но вызывает затруднение именно такой порядок и вообще, наличие 3х объектов, о которых идет речь.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.02.2011, 00:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перегрузка operator<< (C++):

перегрузка operator<< - C++
помогите отгадать в чет ошибка class MCL{ private: int x,y; public: friend ostream&amp; operator&lt;&lt;(ostream &amp;s, MCL &amp;c); }; ...

Перегрузка operator[] - C++
Забыл как перегружать оператор для присваивания значений, а найти не могу ._. Чтобы было вот так: Class A { private: char...

Перегрузка operator= - C++
Возможно ли перегрузить оператор= так, что бы можно было написать? val = {10, 20, 15};

Перегрузка operator+ - C++
при сложени myVector2 = myVector0 + myVector1; выодит сообщения &quot;конструктоор 0&quot; ...1,...2,....2(копирования) а потом деструктор 2,2,1,2...

Перегрузка operator new - C++
Столькнулся с такой проблемой: Есть класс Array, в его конструкторе создается массив int Array::Array(const size_t...

Перегрузка operator= - C++
const Point&amp; operator= (const Point &amp;p) { if (this ==&amp;p) return *this; x = p.x; y = p.y; color = p.color; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
zykis
Сообщений: n/a
22.03.2014, 17:40 #31
Доброе время суток.

Есть очередная задачка - перегрузить оператор вывода таким образом:

Есть три объекта разных классов - А а, В в, С с;

Нужно, чтобы при записи а << b << c; изменялось значение некоторых членов всех трех классов, ну грубо говоря, пусть там есть по одному члену типа float и пусть при такой записи вывода произойдет нечто вроде
b.f+=0.2*c.f;
a.f+=0.8*c.f;

А при любой другой записи - (b<<c<<a, c<<b<<a, b<<a<<c, a<<b<<a) - пусть проводится просто вывод каких-нибудь членов класса, не суть важно. Или даже ошибка за неправильный порядок членов в выводе.

Можно ли это вообще сделать, а если нельзя, то что требуется от этих трех объектов?

Точно известно, что речь про перегрузку вывода, а не перегрузку сдвига.
С перегрузкой я знаком, но вызывает затруднение именно такой порядок и вообще, наличие 3х объектов, о которых идет речь.
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
29
30
31
32
#include <iostream>
 
class B {};
class C {};
class A {
public:
    A operator <<(B b);
    void operator<< (C c);
};
 
A A::operator <<(B b)
{
    //ваш код
    return *this;
}
 
void A::operator <<(C c)
{
   //ваш код
}
 
A aa;
B bb;
C cc;
 
int main()
{
    aa << bb << cc;
//    аналогично вызову
//    (aa.operator <<(bb)).operator <<(cc);
    return 0;
}
Stitch Igorek
45 / 45 / 18
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
22.04.2016, 09:30 #32
Цитата Сообщение от silent_1991 Посмотреть сообщение
компилятор развернёт arr[i] в *(arr + i)
Компилятор то развернет, только запись *(arr + i), более быстродейственна, чем arr[i]. Ну по крайней мере так написано в учебниках.
0
nimazzzy
22.04.2016, 09:39
  #33

Не по теме:

Цитата Сообщение от Stitch Igorek Посмотреть сообщение
только запись *(arr + i), более быстродейственна, чем arr[i].
Нет.

0
Stitch Igorek
45 / 45 / 18
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
22.04.2016, 14:34 #34
Цитата Сообщение от nimazzzy Посмотреть сообщение
Нет.
В языке С существуют два метода обращения к элементу массива: адресная арифметика и индексация массива. Стандартная запись массивов с индексами наглядна и удобна в использовании, однако с помощью адресной арифметики иногда удается сократить время доступа к элементам массива. Поэтому адресная арифметика часто используется в программах, где существенную роль играет быстродействие.

<- цитата с сайта http://cpp.com.ru/shildt_spr_po_c/05/0505.html
0
zss
Модератор
Эксперт С++
6382 / 5947 / 1927
Регистрация: 18.12.2011
Сообщений: 15,264
Завершенные тесты: 1
22.04.2016, 14:38 #35
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
иногда удается сократить время доступа к элементам
Имеется ввиду, например, итераторное обращение к элементам:
C++
1
2
for(int* p=arr;p!=arr+size;++p)
   cout<< *p;
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6472 / 3120 / 306
Регистрация: 04.12.2011
Сообщений: 8,594
Записей в блоге: 4
22.04.2016, 14:41 #36
Тема поднята из глубин небытия, но поскольку всё "новое", это хорошо забытое "старое" хочется что-то изваять. Вот тут тема о вычитании строк:
Написать перегрузку оператора "минус" для строк
Поэтому чуть переделав тот исходник попробую пошутить в этой теме)
Я конечно против перегрузок с неожиданными побочными эффектами, но ради интереса:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <iostream>
using namespace std; 
struct Inta
{
int a;
Inta():a(0){}//по умолчанию
Inta(const int rhs):a(rhs){}//преобразования
Inta(const Inta &rhs):a(rhs.a){}//копирующий
Inta &operator=(Inta &rhs)//присваивания
{
a=rhs.a;
return *this; 
}
 
friend
ostream &operator<<(ostream &os, Inta &rhs);
};
 
struct Intb
{
int b;
Intb():b(0){}//по умолчанию
Intb(const int rhs):b(rhs){}//преобразования
Intb(const Intb &rhs):b(rhs.b){}//копирующий
Intb &operator=(Intb &rhs)//присваивания
{
b=rhs.b;
return *this; 
}
 
friend
ostream &operator<<(ostream &os, Intb &rhs);
};
struct Intc
{
int c;
Intc():c(0){}//по умолчанию
Intc(const int rhs):c(rhs){}//преобразования
Intc(const Intc &rhs):c(rhs.c){}//копирующий
Intc &operator=(Intc &rhs)//присваивания
{
c=rhs.c;
return *this; 
}
 
friend
ostream &operator<<(ostream &os, Intb &rhs);
};
 
struct ABC_out_sequence_Checker
{
static Inta * pa;
static Intb * pb;
static Intc * pc;
static ABC_out_sequence_Checker* ABC_checker;
ostream &cacaut(ostream &os)
{
 
if(pa!=NULL && pb!=NULL && pc!=NULL)
{
//тут поля для вывода в нашем распоряжении и мы можем их изменить: 
pa->a=pb->b+pc->c;//например так
pb->b=pc->c*pa->a;//так
pc->c=pb->b/(pa->a+1);//и так
os<<pa->a<<'\t'<<pb->b<<'\t'<<pc->c;
pa=NULL;
pb=NULL;
pc=NULL;
}
return os;
}
ABC_out_sequence_Checker *get_ABC_ptr()
{
static ABC_out_sequence_Checker abc;
if(ABC_checker==NULL)ABC_checker=&abc;
return ABC_checker;
}
private:
ABC_out_sequence_Checker()
{
if(ABC_checker==NULL)ABC_checker=this;
}
};
Inta *
ABC_out_sequence_Checker::pa = NULL;
Intb *
ABC_out_sequence_Checker::pb = NULL;
Intc *
ABC_out_sequence_Checker::pc = NULL;
 
ABC_out_sequence_Checker*
ABC_out_sequence_Checker::ABC_checker=NULL;
ostream &
operator<<(ostream &os, Inta &rhs)
{
    
    if(
        ABC_out_sequence_Checker::ABC_checker->pa==NULL &&
        ABC_out_sequence_Checker::ABC_checker->pb==NULL &&
        ABC_out_sequence_Checker::ABC_checker->pc==NULL
        )
    {
ABC_out_sequence_Checker::ABC_checker->pa=&rhs;
    }
    
    return ABC_out_sequence_Checker::ABC_checker->cacaut(os);
}
ostream &
operator<<(ostream &os, Intb &rhs)
{
    if(
        ABC_out_sequence_Checker::ABC_checker->pa!=NULL &&
        ABC_out_sequence_Checker::ABC_checker->pb==NULL &&
        ABC_out_sequence_Checker::ABC_checker->pc==NULL
        )
    {
ABC_out_sequence_Checker::ABC_checker->pb=&rhs;
    }   
return ABC_out_sequence_Checker::ABC_checker->cacaut(os);
}
ostream &
operator<<(ostream &os, Intc &rhs)
{
    if(
        ABC_out_sequence_Checker::ABC_checker->pa!=NULL &&
        ABC_out_sequence_Checker::ABC_checker->pb!=NULL &&
        ABC_out_sequence_Checker::ABC_checker->pc==NULL
        )
    {
ABC_out_sequence_Checker::ABC_checker->pc=&rhs;
    }   
return ABC_out_sequence_Checker::ABC_checker->cacaut(os);
}
 
int main()
{
 
Inta a(1);
Intb b(2);
Intc c(3);
 
cout<<a<<b<<c<<endl;
cout<<b<<a<<c;
cout<<c<<a<<b;
cout<<a<<b<<c<<endl;
cin.get();
return 0;    
}

зы прошу извинить за то что не в тему последнего поднятого вопроса
0
Stitch Igorek
45 / 45 / 18
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
22.04.2016, 17:33 #37
Цитата Сообщение от zss Посмотреть сообщение
Имеется ввиду, например, итераторное обращение к элементам:
C++
1
2
for(int* p=arr;p!=arr+size;++p)
* *cout<< *p;
если нет никакой разницы с этим
C++
1
2
for(int i(0); i < size; i++)
* *cout<< arr[i];
то для чего указатель создавать(еще при том условии, что указатель в win_64 равен 8 байт, а int - 4).
К тому же твой вариант цикла будет весьма интересно работать, если параметром arr будет строка=).
0
nimazzzy
22.04.2016, 17:40
  #38

Не по теме:

Цитата Сообщение от Stitch Igorek Посмотреть сообщение
если нет никакой разницы с этим
C++Выделить код
1
2
for(int i(0); i < size; i++)
* *cout<< arr[i];
Разница есть. Операция сложения раз: i++, операция сложения два: arr[i]
C
1
2
for(int* p=arr;p!=arr+size;++p)
    cout<< *p;
Операция сложения раз: ++p. Все.
А вот *(arr + i) и arr[i] - никакой разницы, сколько бы ты не цитировал Шилдта.

0
avgoor
909 / 544 / 118
Регистрация: 05.12.2015
Сообщений: 1,510
22.04.2016, 17:44 #39
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
*(arr + i), более быстродейственна, чем arr[i]
Записи *(arr+i) и arr[i] - эквивалентны.
Что выведет эта программа?
C++
1
2
3
4
5
#include <iostream>
int main()
{
    std::cout<<1["abcd"];
}
0
Stitch Igorek
45 / 45 / 18
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
23.04.2016, 12:20 #40
при помощи этого кода выяснилось, что разница хоть и не большая - но есть.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <time.h>
 
int main()
{
    const int size(30000);
    int arr[size];
    srand(time(NULL));
    //рандомно заполняем массив
    for (int i(0); i < size; i++)
    {
        arr[i] = rand() % 200;
    }
 
    clock_t start, end;
    //засекаем время
    start = clock();
    //сортируем пузырьком обращаясь к массиву при помощи индексации
    for (int i(0); i < (size - 1); i++)
        for (int j(i); j < size; j++)
            if (arr[i] > arr[j])
            {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
    //останавливаем время - выводим на консоль результат
    end = clock();
    std::cout << ((double)end - start) / ((double)CLOCKS_PER_SEC) << std::endl;
    //снова рандомно заполняем
    for (int i(0); i < size; i++)
    {
        arr[i] = rand() % 200;
    }
    //снова засекаем время
    start = clock();
    //снова сортируем пузырьком, но уже обращаемся к элементам массива с помощью адресной арифметики
    for (int i(0); i < (size - 1); i++)
        for (int j(i); j < size; j++)
            if (*(arr + i) > *(arr + j))
            {
                int temp = *(arr + i);
                *(arr + i) = *(arr + j);
                *(arr + j) = temp;
            }
    //снова останавливаем время - выводим на консоль результат
    end = clock();
    std::cout << ((double)end - start) / ((double)CLOCKS_PER_SEC) << std::endl;
 
    system("pause");
    return 0;
}
100.000 элементов первый вариант сортировал 10,633 сек, второй вариант 10,451.
0
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
24.04.2016, 08:38 #41
Stitch Igorek, во-первых, такую разницу можно списать на погрешность. Вы ведь не на операционной системе реального времени запускали код?
Во-вторых, не стоит два бенчмарка в один код пихать. Процессоры нынче умные, умеют и команды исполнять преждевременно, и переупорядочивать их, и переходы по-умному предсказывать, и кэш прогревать, и конвейеры у них длинные...
И всё равно, такая небольшая разница должна быть списана на погрешность измерений и работу в многозадачной среде.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.04.2016, 08:38
Привет! Вот еще темы с ответами:

Перегрузка operator-> () - C++
здравствуйте, объясните пож. как работает operator-&gt; (). Что происходит при этом мне понятно, но непонятно как. template &lt;typename T&gt; ...

Перегрузка operator+ - C++
Нужно сложить число с каждым елементом вектора, вот мой код: MyVectorClass.h namespace program { class MyVectorClass { ...

Перегрузка operator[][][] - C++
Здорова господа!!! Как перегрузить operator для класса или operator ??? Что нужно из него возвращать? От что то пытался но не...

Перегрузка operator->() - C++
Всем привет! Прохожу тему дескрипторов и меня удивляет как работает перегруженный operator-&gt;(). //какой то интерфейс struct...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
24.04.2016, 08:38
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru