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

Создание (вернее, внедрение) манипулятора - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ значение максимальной длины слова http://www.cyberforum.ru/cpp-beginners/thread292933.html
Задан исходный текст на русском языке. длинна текста - не более NL строк, длина строки - не более NS символов, длина слова не более NW символов. исходный текст должен заканчиваться точкой('!','?')....
C++ Посчитать количество слов в строке Здравствуйте! Дайте пожалуйста пример функции которая считает количество слов с строке с помощью функции strtok. Number_Word (char str) return number_words; int _tmain(int argc, _TCHAR*... http://www.cyberforum.ru/cpp-beginners/thread292927.html
сложение двоичных чисел.... C++
Скажите пожалуйста как сложить два двоичных числа!!! программа работает, но не правильно!!!#include <cstdlib> #include <iostream> #include <math.h> #include "Bin.h" using namespace std; Bin...
Разработать функцию обслуживания одного покупателя при условии, что каждый может заказать нужный ему набор блюд, но не более одной порции каждого блюд C++
В буфете предлагают покупателю меню из четырех блюд. Каждое блюдо имеет свою цену и представлено известным количеством порций. Разработать функцию обслуживания одного покупателя при условии, что...
C++ Создание динамического массива используя malloc http://www.cyberforum.ru/cpp-beginners/thread292892.html
Необходимо создать трехмерный динамический массив и заполнить его нулями (допустим B): int i=0; int j=0; int k=0; BYTE ***B = (BYTE ***)malloc(480); for (i=0; i<=479; i++) {
C++ Преобразование Букв в двоичный код Вот надыбал такой код для сабжа #include <iostream> using namespace std; int main() { cout<< "Vvod: "; char s; cin>> s ; подробнее

Показать сообщение отдельно
ValeryLaptev
Эксперт С++
1048 / 827 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
11.05.2011, 10:25
Почитай вот это, может поможет:

Написание собственных манипуляторов
Иногда требуется нестандартный манипулятор. Программирование манипуляторов без аргументов не представляет особой сложности. Для этого надо просто написать функцию, которая получает и возвращает ссылку на поток. Например, пусть нам нужен манипулятор, вставляющий в поток символ табуляции (листинг 14.11).
C++
1
2
3
Листинг 14.11. Манипулятор без аргументов
std::ostream& tab(std::ostream& os)
{    return (os << '\t');  }
Использовать такой манипулятор так же просто, как и стандартный:
C++
1
cout << 12 << tab << 25 << endl;
Обычно манипуляторы без аргументов пишутся для объединения свойств нескольких стандартных манипуляторов. Например, ранее мы рассматривали следующий оператор вывода:
C++
1
cout << setfill('~') << setw(10) << hex << internal << val << endl;
Этот оператор можно записать значительно короче, если объединить все использованные в нем манипуляторы в одной функции (листинг 14.12).
C++
1
2
3
4
5
6
7
Листинг 14.12. «Объединяющий» манипулятор
ostream& setfix(ostream& os)
{    os.width(10); os.fill('~');
    os.setf(ios::internal, ios::adjustfield);
    os.setf(ios::hex, ios::basefield);
    return os;  
}
В результате вывод в cout той же переменной val в том же формате записывается значительно короче:
C++
1
cout << setfix << val << endl;
Написать манипулятор с аргументами несколько сложнее. Собственно, для создания манипулятора, совместимого по интерфейсу со стандартными манипуляторами, нужно разобраться в стандартном механизме реализации. Однако вместо этого можно просто написать некоторый класс, для которого, как обычно, определить функцию operator<<. Джерри Шварц назвал такие классы эффекторами (см. также [12]). Например, пусть нам требуется выводить целые значения в двоичном виде. Напишем класс binary (листинг 14.13).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
Листинг 14.13. «Манипулятор» для двоичного вывода
class binary
{ unsigned long k;
  public:
    binary(unsigned long k): k(k) {}
    friend ostream& operator<<(ostream& os, const binary& t);
};
inline ostream& operator<<(ostream& os, const binary& t)
{ const unsigned long MAX = numeric_limits<unsigned long>::max();
  unsigned long bit = ~(MAX >> 1);                    // старший бит
  while(bit) { os << (t.k & bit?'1':'0'); bit >>= 1; }
  return os;
}
В функции operator<< самыми важными являются две строки:
C++
1
2
const unsigned long MAX = numeric_limits<unsigned long>::max();
unsigned long bit = ~(MAX >> 1);                    // старший бит
В первой строке в переменную MAX заносится максимально возможное беззнаковое целое число, определенное в стандартном классе числовых пределов numeric_limits.

ПРИМЕЧАНИЕ
Класс-шаблон numeric_limits<> определен в заголовоке <limits>.

В двоичной записи это максимальное число представляет собой набор единичных битов:
1111...111
Во второй строке все биты числа сдвигаются вправо на один разряд; самый правый бит (младший разряд числа) теряется; в самый левый бит (старший разряд числа) заносится ноль, так как тип — беззнаковый. Таким образом, в результате сдвига образуется такая конфигурация битов:
0111...111
Потом эта конфигурация инвертируется операцией ~ и превращается в
1000...000
Это значение и заносится в переменную bit. Далее старшая единичка в цикле сдвигается на 1 разряд, пока значение bit не станет равно 0.
Такой класс позволяет нам выводить любые целые в двоичном виде, например:
C++
1
2
short a = -2;
cout << binary(a) << endl;
Однако этот класс выводит в выходной поток всегда такое количество битом, которое содержится в типе unsigned long. Мы легко можем преобразовать этот класс в шаблон, который позволит выводить для беззнаковых целых нужное количество битов (листинг 14.14).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Листинг 14.14. Эффектор-шаблон
// опережающие объявления
template <class T> class binary;
template<class T> ostream& operator<<(ostream& os, const binary<T>& t);
// класс-шаблон
template <class T>
class binary
{ T k;
  public:
    binary(T k): k(k) {}
    friend ostream& operator<< <>(ostream& os, const binary<T>& t);
};
template<class T>
inline
ostream& operator<<(ostream& os, const binary<T>& t)
{ T MAX = numeric_limits<T>::max();
  T bit = ~(MAX >> 1);
  while(bit)
  { os << (t.k & bit?'1':'0'); bit >>= 1; }
  return os;
}
Обратите внимание на опережающие объявления и прототип функции-шаблона operator<< в классе binary.
Использовать данный класс-шаблон в качестве манипулятора можно так:
C++
1
2
3
short a = -2;
cout << binary<unsigned short>(a) << endl;
cout << binary<unsigned char>(128)<< endl;
В результате на экран выводится следующее:
1111111111111110
10000000
Как видим, на экране ровно столько битов, сколько занимают типы unsigned short и unsigned char. Заметим, что использовать в качестве аргумента шаблона знаковый тип нельзя — программа зациклится!
10
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru