Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623

Реализовать operator>>

20.02.2015, 18:29. Показов 1478. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть класс который хранит массив <T> данных в std::vector<T>, задача вывести из него эти данные.
Есть готовый класс но там расписано под каждый тип данных и как то не понятно намудренно.

Buffer.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef BUFFER_CPP_H
#define BUFFER_CPP_H
 
#include <vector>
 
template <class T>
class Buffer
{
    public:
        Buffer(T data[],int size);
        ~Buffer();
        T& operator >> (T& value);
    private:
        std::vector<T> StreamBuf;
        int mTail;
};
 
#endif
Buffer.cpp
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 "Buffer.h"
 
template <class T>
Buffer<T>::Buffer(T data[],int size):
    mTail(0)
{
    this->StreamBuf.clear();
    this->StreamBuf = std::vector<T>(size);
    for (int i = 0; i < size; i++)
        this->StreamBuf[i] = data[i];
}
 
template <class T>
Buffer<T>::~Buffer()
{
    this->StreamBuf.clear();
}
 
template <class T>
T& Buffer<T>::operator >> (T& value)
{
    if (this->StreamBuf.size() <= 0 || (this->mTail+sizeof(T)) > this->StreamBuf.size())    return;
    T buf[sizeof(T)];
    for (int i = this->mTail; i < sizeof(T); i++)
        buf[i] = this->StreamBuf[this->mTail+i];
    this->mTail += sizeof(T);
    return buf;
}
Не могу придумать что мне вернуть на 22 строке.
Вывод компиляции (g++):
In file included from TcpSock/TCP.cpp:2:0,
from main.cpp:2:
TcpSock/../Buffer.cpp: In instantiation of ‘T& Buffer<T>::operator>>(T&) [with T = char]’:
TcpSock/TCP.cpp:189:17: required from here
TcpSock/../Buffer.cpp:22:87: error: return-statement with no value, in function returning ‘char&’ [-fpermissive]
TcpSock/../Buffer.cpp:27:9: error: invalid initialization of non-const reference of type ‘char&’ from an rvalue of type ‘char*’
TCP.cpp
C++
1
2
3
4
5
Buffer<char>buff(buffer,sizeIN);
char msg[sizeIN];
memset(&msg,0,sizeIN);
for (int i = 0; i < sizeIN; i++)
    buff >> msg[i];                         // 189 line
Или все равно нужно расписать под каждый тип данных?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.02.2015, 18:29
Ответы с готовыми решениями:

Реализовать перегрузку operator+() для пользователского класса
Есть класс ДРОБЬ, его члены ЧИСЛИТЕЛЬ И ЗНАМЕНАТЕЛЬ, а методы - конструктор и методы вывода. исходные данные - 4 обычные дроби. мне нужно...

Class & operator's |Error: undefined reference to operator
Компилирует нормально, но когда хочу использовать оператор выдает ошибку:undefined reference to 'operator..(Fraction const&amp;, Fraction...

Класс "Квартира", реализовать 'operator==' сравнивающий площади квартир
Подскажите Где ошыбка? Выдает: #include &lt;iostream&gt; #include &lt;string.h&gt; using namespace std; class flat

7
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
20.02.2015, 18:41
По моим соображениям должно быть что-то типа
C++
1
2
3
4
5
6
7
8
9
10
11
template <class T>
T Buffer<T>::operator >> (T& value)
{
   T buf; 
   buf=static_cast<T>(0);
   if (this->StreamBuf.size() <= 0 || (this->mTail+sizeof(T)) > this->StreamBuf.size())    
        return buf;
    buf = this->StreamBuf[this->mTail];
    this->mTail += sizeof(T);
    return buf;
}
Только какое отношение к этому коду имеет value?
И к вводу-выводу тоже никакого отношения, перегружается оператор сдвига числа на указанное к-во разрядов.
И еще - нельзя возвращать по ссылке локальные переменные.

Кстати, вызов >> должен быть таким
C++
1
2
Buffer<int> bb;
int n=bb>>2;
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.02.2015, 18:46
Реализация шаблона должна быть в хэдэре.

Удалите cpp файл, перетащив его содержимое в хэдэр.
1
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623
20.02.2015, 19:19  [ТС]
zss, Насчет вызова >>, видел в реальном проекте, что допустим объявляли переменную int и в нее записывали именно так:
C++
1
2
int n;
buf >> n;
только в том проекте типы данных расписаны (не шаблон), но он читал в переменную n как и полагается 4 байта.

Хочу повторить тоже самое но юзая шаблон.
В буфер я записываю байты пришедшие из вне (TCP) (char[])
дальше я допустим от клиента отправляю на сокет char (1 byte), int (4 byte) и т.д
А читать вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
char buffer[szBufferIn];
int sizeIN;
memset(&buffer,0,szBufferIn);
 
sizeIN = read(sock,buffer,szBufferIn);
 
Buffer<char>buff(buffer,sizeIN);
char ch;
int n;
// mTail = 0
buff >> ch; // читаем char, mTail + 1
buff >> n; // читаем int , mTail + 4
Файл из реального проекта:

ar.h
Кликните здесь для просмотра всего текста
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef __AR_H__
#define __AR_H__
 
#pragma once
 
#include "HeapMng.h"
 
 
 
class CAr
{
public:
    CAr(void *lpBuf = NULL, u_int nBufSize = 0);
    ~CAr();
 
// Flag values
    enum    { store = 0, load = 1 };
    enum    { nGrowSize = 16384 };
 
    static CHeapMng*    m_pHeapMng;
 
 
// Attributes
    BOOL    IsLoading() const;
    BOOL    IsStoring() const;
 
// Operations
    void    Read( void* lpBuf, u_int nSize );
    void    Write( const void* lpBuf, u_int nSize );
    void    CheckBuf( u_int nSize );
    void    Reserve( u_int nSize );
    void    Flush( void );
    void    ReelIn( u_int uOffset );
 
    // reading and writing strings
    void WriteString(LPCTSTR lpsz);
    LPTSTR ReadString(LPTSTR lpsz );
    LPTSTR ReadString( LPTSTR lpsz, int nBufSize );
 
    LPBYTE  GetBuffer( int* pnBufSize );
    u_long  GetOffset( void );
/*
    void    Copy( CAr & ar );
    CAr& operator = ( CAr & ar );
*/
    // insertion operations
    CAr& operator<<(BYTE by);
    CAr& operator<<(WORD w);
    CAr& operator<<(LONG l);
    CAr& operator<<(DWORD dw);
    CAr& operator<<(float f);
    CAr& operator<<(double d);
 
    CAr& operator<<(int i);
    CAr& operator<<(short w);
    CAr& operator<<(char ch);
    CAr& operator<<(unsigned u);
 
    // extraction operations
    CAr& operator>>(BYTE& by);
    CAr& operator>>(WORD& w);
    CAr& operator>>(DWORD& dw);
    CAr& operator>>(LONG& l);
    CAr& operator>>(float& f);
    CAr& operator>>(double& d);
 
    CAr& operator>>(int& i);
    CAr& operator>>(short& w);
    CAr& operator>>(char& ch);
    CAr& operator>>(unsigned& u);
 
#ifdef __CLIENT
#ifdef _DEBUG
static  DWORD   s_dwHdrPrev;
static  DWORD   s_dwHdrCur;
#endif  // _DEBUG
#endif  // __CLIENT
 
protected:
    BYTE    m_nMode;    // read or write
    u_int   m_nBufSize;
    LPBYTE  m_lpBufCur;
    LPBYTE  m_lpBufMax;
    LPBYTE  m_lpBufStart;
    BYTE    m_lpBuf[nGrowSize];
};
/*
inline void CAr::Copy( CAr & ar )
    {   ASSERT( IsLoading() );  ASSERT( ar.IsStoring() );   ar.Write( (void*)m_lpBufStart, (u_int)( m_lpBufMax - m_lpBufStart ) );  }
inline CAr& CAr::operator = ( CAr & ar )
    {   ar.Copy( *this );   return *this;   }
*/
inline BOOL CAr::IsLoading() const
    { return (m_nMode & CAr::load) != 0; }
inline BOOL CAr::IsStoring() const
    { return (m_nMode & CAr::load) == 0; }
 
inline CAr& CAr::operator<<(int i)
    { return CAr::operator<<((LONG)i); }
inline CAr& CAr::operator<<(unsigned u)
    { return CAr::operator<<((LONG)u); }
inline CAr& CAr::operator<<(short w)
    { return CAr::operator<<((WORD)w); }
inline CAr& CAr::operator<<(char ch)
    { return CAr::operator<<((BYTE)ch); }
inline CAr& CAr::operator<<(BYTE by)
    { CheckBuf( sizeof(BYTE) );
        *(UNALIGNED BYTE*)m_lpBufCur = by; m_lpBufCur += sizeof(BYTE); return *this; }
inline CAr& CAr::operator<<(WORD w)
    { CheckBuf( sizeof( WORD ) );
        *(UNALIGNED WORD*)m_lpBufCur = w; m_lpBufCur += sizeof(WORD); return *this; }
inline CAr& CAr::operator<<(LONG l)
    { CheckBuf( sizeof(LONG) );
        *(UNALIGNED LONG*)m_lpBufCur = l; m_lpBufCur += sizeof(LONG); return *this; }
inline CAr& CAr::operator<<(DWORD dw)
    { CheckBuf( sizeof(DWORD) );
        *(UNALIGNED DWORD*)m_lpBufCur = dw; m_lpBufCur += sizeof(DWORD); return *this; }
inline CAr& CAr::operator<<(float f)
    { CheckBuf( sizeof(float) );
        *(UNALIGNED FLOAT*)m_lpBufCur = *(FLOAT*)&f; m_lpBufCur += sizeof(float); return *this; }
inline CAr& CAr::operator<<(double d)
    { CheckBuf( sizeof(double) );
        *(UNALIGNED double*)m_lpBufCur = *(double*)&d; m_lpBufCur += sizeof(double); return *this; }
 
inline CAr& CAr::operator>>(int& i)
    { return CAr::operator>>((LONG&)i); }
inline CAr& CAr::operator>>(unsigned& u)
    { return CAr::operator>>((LONG&)u); }
inline CAr& CAr::operator>>(short& w)
    { return CAr::operator>>((WORD&)w); }
inline CAr& CAr::operator>>(char& ch)
    { return CAr::operator>>((BYTE&)ch); }
 
#define CAR_SAFE_READ( type, value )    \
    if( m_lpBufCur + sizeof(type) <= m_lpBufMax )   \
        {   value   = *(UNALIGNED type*)m_lpBufCur; m_lpBufCur += sizeof(type); }   \
    else    \
        {   value   = (type)0;  m_lpBufCur  = m_lpBufMax;   }   \
    return *this
 
inline CAr& CAr::operator>>(BYTE& by)
    {   CAR_SAFE_READ( BYTE, by );  }
inline CAr& CAr::operator>>(WORD& w)
    {   CAR_SAFE_READ( WORD, w );   }
inline CAr& CAr::operator>>(DWORD& dw)
    {   CAR_SAFE_READ( DWORD, dw ); }
inline CAr& CAr::operator>>(float& f)
    {   CAR_SAFE_READ( float, f );  }
inline CAr& CAr::operator>>(double& d)
    {   CAR_SAFE_READ( double, d ); }
inline CAr& CAr::operator>>(LONG& l)
    {   CAR_SAFE_READ( LONG, l );   }
 
#include <D3DX9Math.h>
 
inline CAr& operator<<(CAr & ar, D3DXVECTOR3 v)
    {   ar.Write( &v, sizeof(D3DXVECTOR3) );    return ar;  }
 
inline CAr& operator>>(CAr & ar, D3DXVECTOR3& v)
    {   ar.Read( &v, sizeof(D3DXVECTOR3) );     return ar;  }
 
inline CAr& operator<<(CAr & ar, __int64 i)
    {   ar.Write( &i, sizeof(__int64) );    return ar;  }
 
inline CAr& operator>>(CAr & ar, __int64& i)
    {   ar.Read( &i, sizeof(__int64) ); return ar;  }
 
/*
inline CAr& operator<<(CAr & ar, CRect rect)
    {   ar.Write( &rect, sizeof(CRect) );   return ar;  }
 
inline CAr& operator>>(CAr & ar, CRect & rect)
    {   ar.Read( &rect, sizeof(CRect) );    return ar;  }
*/
 
inline CAr& operator<<(CAr & ar, RECT rect)
    {   ar.Write( &rect, sizeof(RECT) );    return ar;  }
 
inline CAr& operator>>(CAr & ar, RECT & rect)
    {   ar.Read( &rect, sizeof(RECT) ); return ar;  }
 
inline CAr& operator<<(CAr & ar, PLAY_ACCOUNT pa)
    {   ar.Write( &pa, sizeof(PLAY_ACCOUNT) );  return ar;  }
 
inline CAr& operator>>(CAr & ar, PLAY_ACCOUNT& pa)
    {   ar.Read( &pa, sizeof(PLAY_ACCOUNT) );   return ar;  }
            
inline u_long CAr::GetOffset( void )
{
    ASSERT( IsStoring() );
    return( m_lpBufCur - m_lpBufStart );
}
 
#endif //__AR_H__


А далее в коде я видел именно такой вывод, что описал выше.
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
20.02.2015, 19:47
Цитата Сообщение от Путин Посмотреть сообщение
именно такой вывод
Возможно этом примере перегружен operator>> таким образом
C++
1
2
3
4
5
istream& operator>>(istream& is, T& x)
{
  // чтение из потока is данных преременной x
   return is;
}
Обратите внимание, что эта функция глобальная (не принадлежит классу T).
Поэтому слева от операции можно написать переменную потока (например is), а справа - переменную класса (x):
C++
1
is>>x;
У Вас же перегружается operator>> - член класса Buffer. Поэтому, слева должна быть переменная типа buffer, т.е.
C++
1
2
3
4
5
6
Buffer<char> buff(buffer,sizeIN);
char ch;
сh=buff >> 'a'; // читаем char, mTail + 1
Buffer<int> buff(buffer,sizeIN);
int n;
n=buff >> 2; // читаем int , mTail + 4
Кстати, можете справа написать переменную.
При передаче по ссылке она получит значение.
Тогда действительно выражение
C++
1
buff>>n;
будет осмысленным.
Но в Вашей функции переменной value ничего не присваивается.
1
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623
20.02.2015, 19:53  [ТС]
zss, а цифра "2" это чтобы bb понял, что нам нужен int ? или не так?
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
20.02.2015, 20:03
Лучший ответ Сообщение было отмечено Путин как решение

Решение

Предлагаю такой вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T>
Buffer<T>&  Buffer<T>::operator >> (T& value)
{
   T buf; 
   buf=static_cast<T>(0);
   if (this->StreamBuf.size() > 0 && (this->mTail+sizeof(T)) <= this->StreamBuf.size()) 
   {  
      buf = this->StreamBuf[this->mTail];
      this->mTail += sizeof(T);
   }
   
   value=buf;
    
   return *this;
}
Тогда можете писать даже так
C++
1
buff>>n>>m;
1
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623
20.02.2015, 20:07  [ТС]
zss, Спасибо за объяснения, то что надо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.02.2015, 20:07
Помогаю со студенческими работами здесь

Структура как ключ map, возможно ли как-то реализовать operator []
Возможно бред, но всё же. Реализовать сам ключ не сложно, вот код: class cKey { public: cKey(){} cKey(TIMER_ID...

operator char() или operator int()
Здорова госпдо! Снова ничо не ясно как всегда. Разбираю программку из книги Страуструпа, там он описывает класс String в нем есть ...

Вызов operator[] через operator[] const
Перелистывал Майерса, наткнулся на код, подскажите пожалуйста почему он советует закомментированный вариант кода, не проще сделать как...

Перегрузка operator>> и operator<< в абстрактном классе
Здрасьте! Есть необходимость перегрузить потоки, Я знаю как это сделать через friend, но вот кажется что есть и другое решение. Попытался...

Реализация operator + через operator +=
внутри следующей темы возник вопрос, ответ на который так и не был получен: ...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru