2009-11-25 4 views
0

Я пишу часть сотевера, которая нуждается в объектах, которые обмениваются сообщениями друг с другом. Сообщение должно иметь следующее содержание:C++ сообщение, которое вызывает сомнения

Peer *srcPeer; 
const char* msgText; 
void* payload; 
int payLoadLen; 

сейчас, Peer должен быть указателем, как у меня есть еще один класс, который управляет сверстниками. В остальном я сомневаюсь ... например, я могу скопировать текст сообщения и полезную нагрузку (путем выделения двух новых буферов) по мере создания сообщения, а затем поместить удаления в деструктор сообщения. Это имеет большое преимущество в том, чтобы не забывать о стираниях в потребительских функциях (не говоря уже о том, чтобы упростить эти функции), но это приведет к большому количеству копий & и может сделать все медленным. Поэтому я могу просто указать указатели и все еще удалить деструктор eveything ... или ... ну, это обычная ситуация, когда на других языках программирования нет даже дилеммы, так как есть GC. Каковы ваши предложения и какие самые популярные методы?

Редактировать: Я имею в виду, что я хотел бы знать, какие лучшие методы для передачи содержимого ... например, если у вас есть другой объект, который отслеживает их или, возможно, общие указатели ... или что вы будете делать ...

ответ

1

Если все сообщения схожи, подумайте об использовании стека мусора (http://library.gnome.org/devel/glib/stable/glib-Trash-Stacks.html) - таким образом, вы можете сохранить стек выделенных, но неинициализированных структур сообщений, которые вы можете использовать повторно, не принимая постоянные malloc/бесплатный хит.

+0

Меня беспокоило не о распределении сообщений ... а о передаче контента. Каковы лучшие стратегии ... Я изменю свой вопрос. – gotch4

2

Вам нужно очистить ownership: когда сообщение передается между сверстниками, изменилось ли владение? Если вы переключите право собственности, просто попросите ресивера выполнить очистку.

Если вы просто «сдадите в аренду» сообщение, убедитесь, что у вас есть процедура «вернуться к владельцу».

Общее сообщение? Тогда вам, вероятно, понадобится некоторое копирование или имеют мьютексы для защиты доступа.

+0

@ gotch4: мой ответ удовлетворяет вас? – jldupont

0

Рассмотрите возможность использования shared_ptr<>, доступный от Boost, а также часть библиотеки std::tr1, а не сырые указатели. Это не лучшее, что можно использовать во всех случаях, но похоже, что вы хотите, чтобы все было просто, и это очень хорошо. Это локальная сборка мусора.

0

В C++ нет правил или даже лучших практик, за исключением тех случаев, когда вы принимаете дизайнерское решение о владении указателем и придерживаетесь его.

Вы можете попытаться применить определенную политику с помощью интеллектуальных указателей или просто задокументировать настроенное поведение и надеяться, что все прочитают руководство.

0

В C++, вы можете иметь ссылки подсчета тоже, как здесь:

http://library.gnome.org/devel/glibmm/stable/classGlib_1_1RefPtr.html

В этом случае, вы можете передавать объекты Glib :: RefPtr. Когда последний из этих RefPtr-s уничтожается, связанный с указателем, объект удаляется сам.

Если вы не хотите использовать glibmm, вы можете реализовать его тоже, это не слишком сложно. Кроме того, вероятно, STL и boost тоже имеют что-то подобное.

Просто следите за круглыми ссылками.

0

Простейшей задачей является использование объектов для управления буферами.Например, вы можете использовать std::string как для членов msgText, так и для payload, и вы можете покончить с payLoadLen так же, как и по методу payload.size().

Если и только если измерить производительность этого решения и акт копирования msgText и payload вызывала неприемлемое снижение производительности, вы можете выбрать, используя общий указатель на структуру, которая разделялась копьями сообщения.

В (почти) никакой ситуации я бы не полагался на запоминание вызова delete в деструкторе или вручную записи безопасного оператора копирования и копирования.

0

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

Каждый владелец отвечает за очистку объекта сообщения.

+0

hmmm ... звучит как ленивый подход ко мне. – jldupont

+0

Да, так же, как использование Java вместо ассемблера: перейдите на один уровень абстракции, чтобы избавиться от множества проблем. Эрланг использует этот подход с большим успехом. –