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

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

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

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

17.02.2011, 00:10. Просмотров 6807. Ответов 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; ...

40
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
17.02.2011, 00:15 #2
http://www.cyberforum.ru/cpp-beginners/thread42898-print.html
friend функция С++ на MSVC 6.0
http://www.cyberforum.ru/cpp/thread162537.html

посмотрите, подобное уже решалось
0
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
17.02.2011, 08:56  [ТС] #3
Немного не то.

Я хочу не просто перегрузить оператор в трех классах, а сделать так, чтобы перегруженная операция выполнялась только в случае определенного порядка трех объектов разных классов:

Или даже так - для a<<b<<c выполняется одна версия cout, для любого другого a<<b, b<<a<<c, c<<b<<a - другая.
0
Хохол
Эксперт С++
475 / 443 / 13
Регистрация: 20.11.2009
Сообщений: 1,292
17.02.2011, 09:04 #4
Невозможно это.
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
17.02.2011, 13:50 #5
Если раскомментировать какие-либо из закомментированных выражений, то выдает ошибку:
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
/////////////////////////////////////////////////////////////////////////////////////////
//Есть очередная задачка - перегрузить оператор вывода таким образом:
//
//Есть три объекта разных классов - А а, В в, С с;
//
//Нужно, чтобы при записи а << 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х объектов, о которых идет речь. 
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string  T_str;
/////////////////////////////////////////////////////////////////////////////////////////
class  T_base
{
    float  val_;
    //-----------------------------------------------------------------------------------
public:
    T_base(float  val) : val_(val)
    {}
    //-----------------------------------------------------------------------------------    
    void  set_zero()
    {
        val_ = 0;    
    }
    //-----------------------------------------------------------------------------------
    operator float()
    {
        return  val_;
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
class  A : public T_base
{
public:
    A() : T_base(1)
    {}
};
/////////////////////////////////////////////////////////////////////////////////////////
class  B : public T_base
{
public:
    B() : T_base(2)
    {}
};
/////////////////////////////////////////////////////////////////////////////////////////
class  C : public T_base
{
public:
    C() : T_base(3)
    {}
};
/////////////////////////////////////////////////////////////////////////////////////////
class AB
{
    A&  a_;
    B&  b_;
    //-----------------------------------------------------------------------------------
public:
    AB(A&  a, B&  b) : a_(a), b_(b)
    {}
    //-----------------------------------------------------------------------------------
    AB(const AB&  ab) : a_(ab.a_), b_(ab.b_)
    {}
    //-----------------------------------------------------------------------------------
    void  operator<< (C&  c)
    {
        a_  .set_zero();
        b_  .set_zero();
        c   .set_zero();
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
AB  operator<< (A&  a, B&  b)
{    
    return  AB(a, b);    
}
/////////////////////////////////////////////////////////////////////////////////////////
void  print
    (
        T_str  message,
        A      a,
        B      b,
        C      c
    )
{
    std::cout << message
              << std::endl
              << a
              << " "
              << b
              << " "
              << c
              << std::endl
              << std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    std::locale::global(std::locale(""));
    A  a;
    B  b;
    C  c;
 
    print("Исходные значения:", a, b, c);
      
    //Если раскомментировать какие-либо из нижерасположенных выражений, то выдает ошибку.
    //a << c << b;   
    //b << a << c;
    //b << c << a;
    //c << a << b;
    //c << b << a; 
 
    //a << b << a;
   
    a << b << c;
    print("После оператора a << b << c:", a, b, c);
}
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
17.02.2011, 14:47 #6
Mr.X, ТСу вроде надо было перегрузить оператор передачи в поток (для которого первым операндом является экземпляр std::ostrem), а не просто оператор сдвига.
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
17.02.2011, 15:15 #7
Цитата Сообщение от silent_1991 Посмотреть сообщение
Mr.X, ТСу вроде надо было перегрузить оператор передачи в поток (для которого первым операндом является экземпляр std::ostrem), а не просто оператор сдвига.
У автора вот так написано:
Цитата Сообщение от Selendis Посмотреть сообщение
Нужно, чтобы при записи а << b << c; изменялось значение некоторых членов всех трех классов
Да и перегрузить можно только встроенный оператор, а оператор вывода «<<» - это перегрузка оператора сдвига.
0
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
17.02.2011, 15:21 #8
вот мой вариант

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
#include <iostream>
#include <sstream>
#include <string>
 
using namespace std;
 
class Base{
public:
  virtual string toString() = 0;
};
 
class A : public Base{
public:
  string toString(){ return "a"; }
};
 
class B : public Base{
  string toString(){ return "b"; }
};
 
class C : public Base{
  string toString(){ return "c"; }
};
 
class Manager{
private:
  unsigned uCount;
  stringstream str;
  bool bIsGood;
public:
  Manager() : uCount(0), str( stringstream::in | stringstream::out ), 
                     bIsGood( true )
  {
  
  }
 
  void out( ostream& os, Base* b ){
    if( bIsGood ){
      switch( uCount ){
      case 0:
         if( !dynamic_cast<A*>( b ) ){
           bIsGood = false;
         } 
         break;
      case 1:
         if( !dynamic_cast<B*>( b ) ){
           bIsGood = false;
         } 
         break;
      case 2:
         if( !dynamic_cast<C*>( b ) ){
           bIsGood = false;
         } 
         break;     
      }
      if( bIsGood ){
         str << b->toString();
      }else{
         str.str("");
      }
    }
 
    if( 2 == uCount ){
      if( bIsGood ){
         os << str.str();
      }
      uCount = 0;
      bIsGood = true;
    }else{
      ++uCount;
    }
  }
};
 
Manager man;
 
#define MACRO( OS, OBJ ) \
  man.out( OS, &OBJ );   \
  return OS;
  
 
ostream& operator<<( ostream& os, A& obj ){
  MACRO( os, obj );
}
 
ostream& operator<<( ostream& os, B& obj ){
  MACRO( os, obj );
}
 
ostream& operator<<( ostream& os, C& obj ){
  MACRO( os, obj );
}
 
int main(){
  A a;
  B b;
  C c;
 
  cout << a << b << b << endl;
  cout << a << b << c << endl;
  cout << b << a << c << endl;
  cout << a << b << c << endl;
 
}
Bash
1
2
3
4
5
[alexxx@localhost ~]$ ./a.out 
 
abc
 
abc
Добавлено через 4 минуты
про изменение полей объектов, тут уже в каждом операторе отдельные действия
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
17.02.2011, 16:51 #9
Mr.X,
Цитата Сообщение от Mr.X Посмотреть сообщение
У автора вот так написано:
А ещё у автора написано
Цитата Сообщение от Selendis Посмотреть сообщение
Точно известно, что речь про перегрузку вывода, а не перегрузку сдвига
Цитата Сообщение от Mr.X Посмотреть сообщение
Да и перегрузить можно только встроенный оператор, а оператор вывода «<<» - это перегрузка оператора сдвига.
Ну вы ведь меня поняли и просто придираетесь, правда? Ладно, для большей конкретики так:
"ТСу нужна была реализация перегрузки оператора сдвига влево для передачи своего правого операнда в поток, представляемый левым операндом, плюс выполнить некие дополнительные действия."
0
Selendis
1 / 1 / 0
Регистрация: 15.02.2011
Сообщений: 43
17.02.2011, 18:15  [ТС] #10
silent_1991: Вы очень круты. Я и сам не знал, что мне нужно именно это!
Ведь правда - мне конечно нужна реализация оператора вывода. Однако реализация сдвига, которая будет выводить - это вообще супер.

Дальше уже понятно, как это доработать, спасибо.
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
17.02.2011, 18:32 #11
Цитата Сообщение от Selendis Посмотреть сообщение
Вы очень круты
Никогда тугодумом не был, но немного не понял - это что, сарказм? Если нет - извиняюсь. А если так - то я основывался именно на вашей фразе
Цитата Сообщение от Selendis Посмотреть сообщение
Точно известно, что речь про перегрузку вывода, а не перегрузку сдвига.
Суть в том, что оператор << и есть оператор сдвига влево, просто для класса basic_ios (вроде для него, ну или для производных) он перегружен как оператор вывода в поток.
0
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
17.02.2011, 18:54 #12
оператора вывода просто не существует)
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
17.02.2011, 19:09 #13
alex_x_x, ну ведь на нашем уровне абстракции мы имеем право "забыть", что в контексте ввода/вывода используются именно операторы сдвигов и для понятности называть их операторами ввода/вывода.
0
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
17.02.2011, 19:14 #14
silent_1991, так же как == != для объектов -> для умных указателей, [] для множеств итп
0
silent_1991
Эксперт С++
4989 / 3046 / 149
Регистрация: 11.11.2009
Сообщений: 7,028
Завершенные тесты: 1
17.02.2011, 19:18 #15
alex_x_x, не понял аналогии, все приведённые вами операции работают в соответствии с их назначением в, так сказать, реальной жизни. Операторы сравнения действительно сравнивают, а оператор индексации действительно даёт доступ к нужному элементу. А вот сдвиг работает не так, как надо, он не сдвигает, а выполняет иную функцию. Поэтому я и предлагаю чисто формально "забыть", что это именно оператор сдвига)))
0
17.02.2011, 19:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2011, 19:18
Привет! Вот еще темы с ответами:

Перегрузка 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...


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

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

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