Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как сделать объект переменной длины?  (Прочитано 14737 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Predicate
Гость
« : 20-09-2004 05:56 » 

Уважаемые, стоИт цель создать класс (или иерархию классов), представляющий из себя, скажем так, структуру переменной длины... А конкретнее, представить сетевой пакет объектом. Чтобы можно было передавать указатель на этот объект в функции, как массив байт... Проблема как раз в том, что пакеты в общем случае разной длины, скажем поле данных различно по длине всегда.
В голову приходит только одно решение: помимо полей заголовка (стандартных) завести в классе указатель и выделять требуемое количество памяти непосредственно под данные (соответственно указатель будет указывать (тафтология, сорри) на выделенный массив; и добавить переменную, хранящую длину данных. И переопределить в классе операцию приведения к типу "указатель на массив байт". Причем для этого придется сделать статическую переменную класса - указатель на массив, а внутри операции приведения типа выделять память под пакет и конструировать пакет так, как он должен выглядеть при передаче. Т.е. на самом деле организовать это все дело по типу некоторых функций сокетов, которые возвращают, скажем, строки в собственном буфере библиотеки, и хранятся эти данные гарантированно только до следующего вызова функции сокетов.
Чувствую, что это извратный метод, однако ничего другого в голову не приходит... Жаль Может кто-нибудь делал что-нить подобное?
И еще один вопрос: статические члены класса уникальны в пределах одной программы? Или потока?
Заранее спасибо Улыбаюсь
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 20-09-2004 06:25 » 

что же тут извратного?

пусть имеется указатеь

BYTE *pMyData;

в конструкторе класса:

pMyData=NULL;

в коде, когда понадобилось выделить память:

pMyData=new BYTE[N];

(если память удачно выделилась, то указатель станет !=NULL)

если стало надо изменить размер, то:

UINT i;
BYTE pOldData=pMyData;
pMyData=new[N1];
if(N1>=N)
{
//копируем
for(i=0;i<N;i++) pMyData=pOldData;
}
else
{
//обрезаем(или что там надо) старые данные
for(i=0;i<N1;i++) pMyData=pOldData;
}
N=N1;//новая длина
delete [] pOldData;//чистка памяти
Записан

Predicate
Гость
« Ответ #2 : 20-09-2004 07:26 » 

Хех... спасибо конечно за НАСТОЛЬКО полный ответ, но выделять и удалять память я вроде как умею (немножко Улыбаюсь ). Меня больше интересовал подход... В смысле сама идея. В том методе, который мне пришел в голову, меня смущает в основном то, что могут быть проблемы в многопоточных приложениях. Вопрос в том: насколько уникальны статические члены класса? Т.е. в частности, будет ли статическая переменная-член класса одна в пределах всего приложения, процесса или потока?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 20-09-2004 08:43 » new

Predicate, вообще-то, если ты её(переменную) определяешь внутри процедуры потока (или просто функции или класса или структуры - чего угодно) , то она только там и есть. Для доступа к одной и той же переменной из разных объектов используются указатели или оператор "." . Ну, еще к глобальной можно обратитться напрямую.

А если определить с private, то прямой доступ к переменной - только из самого класса.

А вообще - ты же могешь для каждого конкретного примера запросто это проверить - из одного объекта присваивай одно значение, из другого - другое. И сравнивай содержимое переменных.
Записан

NetRaider
Гость
« Ответ #4 : 20-09-2004 08:44 » 

Цитата: Predicate

... помимо полей заголовка (стандартных) завести в классе указатель и выделять требуемое количество памяти непосредственно под данные (соответственно указатель будет указывать (тафтология, сорри) на выделенный массив; и добавить переменную, хранящую длину данных. И переопределить в классе операцию приведения к типу "указатель на массив байт". Причем для этого придется сделать статическую переменную класса - указатель на массив, а внутри операции приведения типа выделять память под пакет и конструировать пакет так, как он должен выглядеть при передаче.


Это все сильно похоже на описание класса std::string - в спецификации не указано, в каком формате хранится строка - это может быть список, массив, либо некая структура, только вместо оператора приведения к 'char*' существует функция c_str() в результате которой объект класса должен собрать строку в один непрерывный кусок и вернуть клиенту указатель на него(возможно это потребует выделения памяти(под копию) и ее освобождения при, например повторном вызове c_str).
 
Не пойму только зачем мучаться со статическими переменными(100% проблемы при многопоточности - одна на процесс.) Обычная переменная и все...
Записан
NetRaider
Гость
« Ответ #5 : 20-09-2004 08:46 » 

Цитата: NetRaider
...вместо оператора приведения к 'char*'


читать ''к 'const char*'"
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 20-09-2004 10:55 » 

NetRaider,
Цитата

Не пойму только зачем мучаться со статическими переменными(100% проблемы при многопоточности - одна на процесс.) Обычная переменная и все...


эт точно Улыбаюсь
кстати - не помню ни разу, когда бы я пользовался статик-переменными Улыбаюсь

обычно в таких случаях у меня сихронизация флагами
Записан

Predicate
Гость
« Ответ #7 : 20-09-2004 11:32 » 

Цитата: NetRaider

Не пойму только зачем мучаться со статическими переменными(100% проблемы при многопоточности - одна на процесс.) Обычная переменная и все...


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

ru
Offline Offline

« Ответ #8 : 20-09-2004 22:53 » 

Цитата: Predicate
Т.е. в частности, будет ли статическая переменная-член класса одна в пределах всего приложения, процесса или потока?


На rsdn была статья по паттерн Одиночка (Singleton),  как раз он подойдет в этом случае (если система объектно - орентированная)

http://www.rsdn.ru/article/patterns/singleton.xml
http://www.rsdn.ru/forum/Message.aspx?mid=531461

а также есть готовое решение в boost
Записан
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #9 : 21-09-2004 08:57 » 

Narod,

ja ne znaju, esli komu-to nado - ja gde-to kogda-to (w prozesse rabochego wremeni  i besplatnogo ineta Отлично ) skachala angl. versiju knigki (Iskala russkuju versiju, no ne nashla  Жаль  )   ):

Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования

 Posemu esli komu-to nado, mogu skinut.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
dedOK
Гость
« Ответ #10 : 01-11-2004 08:52 » 

Довольно много писали о динамических массивах, многопоточности. И только немного упомянули std::string.

Хотелось бы добавить, что в стандартной библиотеке есть полный набор динамических контейнеров. Например, std::vector - обычный линейный массив, который "хранит" число элементов. Его можно было бы использовать.

std::string реализует C-строку. Сами строки хранятся отдельно со счетчиками ссылок. Поэтому использовать string просто как массив байт не совсем эффективно.

К тому же все классы контейнеры позволяют пользователю настраивать способ распределения памяти через параметр шаблона allocator. Однако, это требуется не часто. Стандартные аллокаторы поддерживают многопоточность.

ИМХО, std::vector<unsigned char> (со стандартным аллокатором) вполне бы подошел для хранения пакетов.
Записан
michaelprog
Гость
« Ответ #11 : 11-05-2005 08:54 » 

мальнькое замечание stl по определению НЕ ПОТОКОБЕЗОПАСНА
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines