Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.01.2011, 00:18   #11
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

СпасибО, я в курсе
Лучше объясните мне как перегружать оператор ввода???
Помог - жми весы
S1av0k вне форума Ответить с цитированием
Старый 20.01.2011, 01:40   #12
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
Радость

Примерно так:
Код:
	istream& operator >> (istream& s, String& qw)
	{
                // Тут память выделяешь или в конструкторе 
                // заранее выделяй, тогда тут не надо будет
		qw.mass = new char [10];
		s>>qw.mass;
		return s;
	}
An1ka вне форума Ответить с цитированием
Старый 20.01.2011, 01:52   #13
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

Дело в том, что operator >> - это друг класса, поэтому доступен в перегрузке "только для чтения".
И вторая проблема: как узнать, сколько выделять памяти?
Помог - жми весы
S1av0k вне форума Ответить с цитированием
Старый 20.01.2011, 02:21   #14
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Цитата:
Кстати, Obey-Kun, а как Вы пишете собственные классы, если не умеете перегружать операторы ввода/вывода?
Это не операторы ввода/вывода, а операторы сдвига (битовая операция). Другое дело, что ты их используешь для работы с потоками, как принято в C++. А с потоками я не работал толком, это да. Не приходилось, вот и всё.

Цитата:
И вторая проблема: как узнать, сколько выделять памяти?
Например? Где?
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su
Obey-Kun вне форума Ответить с цитированием
Старый 20.01.2011, 02:30   #15
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

Просто, насколько я понимаю, если не перегружать оператор, то придется делать отдельную функцию-член класса, которая выводит данные....
В моём случае я представляю это только как-то так:
Код:
void String::show_smth()
 {
    cin >> mass; 
 }
Вот только как я понимаю, cin сработает только в консольном приложении....а если я захочу прикрутить GUI? Как Вы поступали в таком случае?..

А про память:
Код:
istream& operator >> (istream& s,const String& qw)	
	{
		qw.mass = new char [];
		s >> qw.mass;
		return s;	
	}
Например тут. Мне ведь нужно выделить память прежде чем заполнить qw.mass из потока...А сколько её выделить?....как это узнать?...
Помог - жми весы

Последний раз редактировалось Stilet; 20.01.2011 в 07:56.
S1av0k вне форума Ответить с цитированием
Старый 20.01.2011, 02:59   #16
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Что-то типа new char[strlen(qw.mass)+1].
Добавлять единицу надо так как туда дописывается символ конца строки (/0). Если не ошибаюсь.

Цитата:
Просто, насколько я понимаю, если не перегружать оператор, то придется делать отдельную функцию-член класса, которая выводит данные
Ну да, верно. Просто это как-то мимо меня прошло, к гуям довольно шустро перешёл. Но эти операторы называются не операторами ввода (вывода), а операторами битового сдвига влево (вправо).
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su

Последний раз редактировалось Obey-Kun; 20.01.2011 в 03:09.
Obey-Kun вне форума Ответить с цитированием
Старый 20.01.2011, 03:29   #17
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

Да, спасибо.
Но это не выход. Есть ещё такая беда: оператор доступен только для чтения, так как друг....к тому же память нужно выделять так, чтобы её ровно хватило на то, чтобы в qw.mass записать всё то, что введено в поток... [length+1] точно маловато, особенно, если объект создался пустым конструктором и его length = 0.
Выхода так и нет.
Помог - жми весы
S1av0k вне форума Ответить с цитированием
Старый 20.01.2011, 03:34   #18
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Упс. Я всё выше неправильно понял. Не обратил внимание на то, что за метод пишем . Сейчас погуглю...

Гугл привёл туда: http://bytes.com/topic/c/answers/877...tream-string-s
Там прямо как у тебя задание. И проблема та же.

Ему посоветовали не реаллокатить каждый раз память (ибо это неэффективно, а увеличивать, если не хватает места. Я тут с ним полностью согласен. То же самое применяется в контейнерах STL (vector и проч.) — при превышении выделенной памяти, она реаллокатится с удвоенным размером.
Цитата:
Here is the problem, as you say you have no idea how many characters you are going to get input so you can not allocate enough data in advance, that means that every-time you store a new character in the String the first thing you have to check is if there is enough data to store the character. If there isn't then you must reallocate the Strings internal array.

Here is the crunch, if you store the data you have (size and pointer) that implies that the size is the exact size of the String, every time you store a new character you will need to reallocate, that will be very inefficient (but it would work).

What would be better is to have a array that is at least big enough to store the string but may be bigger. Strings private data should contain 3 members, size, capacity and pointer where size is the actual size of the string and capacity is the current size of the buffer. That way the buffer size can be larger than the string size. Then when you allocate extra data you can expand the buffer by more than a single character which means you wont have to allocate every time you store an extra character.

What allocation algorithm you use is up to you, it could be something simple like +10 characters, I have sometimes used *1.6 of the current size which is a fairly efficient growth algorithm for its complexity.
Но это всё не по теме. А по теме я нагуглил вот что:
Код:
MyString::MyString()
{
str_length = 1;
DATA = new char[str_length];
memcpy(DATA,"",str_length);
}


ostream& operator << (ostream& OS, MyString & S)
{
return OS << S.get_string();
}

istream& operator >> (istream& IS, MyString & S)
{
char* input = new char[100];
IS.getline(input,100);
S.set_data(input,S);
delete[] input;
return IS;
}

void MyString::set_data(char *input, MyString &S)
{
str_length = strlen(input)+1;
DATA = new char[str_length];
memcpy(DATA,input,str_length);
}
Вот так. Думаю, исходя из этого кода, тебе не составит труда дописать свой. Хотя set_data лучше оптимизировать с учётом вышесказанно (а именно делать new только по необходимости).
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su

Последний раз редактировалось Stilet; 20.01.2011 в 08:03.
Obey-Kun вне форума Ответить с цитированием
Старый 20.01.2011, 07:36   #19
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от S1av0k Посмотреть сообщение
А про память:
Код:
istream& operator >> (istream& s,const String& qw)	
	{
		qw.mass = new char [];
		s >> qw.mass;
		return s;	
	}
Например тут. Мне ведь нужно выделить память прежде чем заполнить qw.mass из потока...А сколько её выделить?....как это узнать?...
А как можно узнать заранее сколько пользователь захочет ввести символов ? Никак ! Но для этих целей можно использовать глобальный буфер.
Код:
#define MAX_CHAR 256
char mybuffer[MAX_CHAR];

	istream& operator >> (istream& s, String& qw)
	{
		// Обнуляем
		memset ( mybuffer, 0, MAX_CHAR);
		// Вводим в буфер
		s>>mybuffer;
		// Проверяем размер строки
		int i =strlen ( mybuffer);
		// Создаем массив +1 нуль строка
		qw.mass = new char [i+1];
		// Копируем строку из буфера
		strcpy ( qw.mass, mybuffer);
		// Строка оканчивается на 0
		qw.mass[i] ='\0';
		return s;
	}
Функция должна быть написана вне класса !
Потом используем так:
Код:
// Создаем класс
String abc;
// Вводим текст
cin >> abc;
Не знаю чему вас там учат !! Вот смотри, всё работает и никаких "друзей" и констант не надо !! Ты ведь записываешь в память !
И про высвобождение динамической памяти не забывай
An1ka вне форума Ответить с цитированием
Старый 20.01.2011, 07:48   #20
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

На кой чёрт буфер делать глобальным? Область видимости должна быть минимально необходимой. В остальном то же, что я написал в предыдущем посте. На разве что в реализации метода вместо метода getline использован оператор сдвига влево.

p.s.: не нуль-строка, а нуль-символ, про терминологию можете почитать здесь — http://ru.wikipedia.org/wiki/%D0%9D%...BE%D0%BA%D0%B0
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su

Последний раз редактировалось Obey-Kun; 20.01.2011 в 07:56.
Obey-Kun вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как обойти "преобразование типа из "string" в "float" невозможно" lexluter1988 Помощь студентам 1 07.08.2010 12:23
классы вида for="..." и class="A B C" Darkstar100 HTML и CSS 5 19.01.2010 20:06
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04