Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Модульность - структура прокси-классов (число прочтений - 2659 )
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Модульность - структура прокси-классов
21. Марта 2008 :: 09:58
Печать  
Между различными модулями должно происходить взаимодействие. Соответственно, наружу из различных модулей должны торчать некоторые классы. Чтобы можно было модифицировать взаимодействующие классы без необходимости перекомпиляции модулей, взаимодействие должно происходить не напрямую, а через классы-обертки - прокси классы. Прокси-классы должны быть жестко фиксированы и никогда не меняться (по возможности) в будущем. Ну, конечно, кроме случаев расширения интерфейса.

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

Код
Выбрать все
class RealClass {
public:
void SomeMethod () {...}
};

class ProxyClass {
boost::shared_ptr<RealClass> m_pImpl;
public:
void SomeMethod () {m_pImpl->SomeMethod ();}
};
 



В этом случае объекты прокси-классов одновременно являются смартпойнтерами - их можно свободно копировать и передавать по значению. Проблема здесь, ИМХО, использование boost::shared_ptr - его структура достаточно нетривиально (в частности, из-за завязок на weak_ptr), поэтому не исключено, что в следующих версиях Буста shared_ptr будет сильно изменен, что приведет к невозможности взаимодействия модулей с разными версиями Буста.

Возможно, более удачным будет такой вариант:
Код
Выбрать все
class RealClass {
public:
void SomeMethod () {...}
};

class ProxyClass {
boost::scoped_ptr<RealClass> m_pImpl;
public:
void SomeMethod () {m_pImpl->SomeMethod ();}
};
 


Здесь shared_ptr заменен на scoped_ptr. В результате прокси-класс перестал быть смартпойнтером и стал некопирабельным. Если требуется смартпойнтер, то он может быть создан явно на стороне вызывающего модуля:
Код
Выбрать все
typedef boost::shared_ptr<ProxyClass> RealClassPtr;
 


scoped_ptr имеет крайне простую структуру - фактически, это просто класс, хранящий обычный указатель и удаляющий объект в деструкторе. Поэтому, считаю, scoped_ptr вряд ли будет меняться в следующих версиях Буста.

Так же scoped_ptr хорош тем, что он некопирабелен. В этом он имеет преимущество перед std::auto_ptr. В случае auto_ptr у нас появлялись бы некорректные объекты прокси-классов.

Может быть, для построения прокси-классов стоит вообще отказаться от Буста и реализовать некий шаблонный класс, похожий на scoped_ptr.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Модульность - структура прокси-классов
Ответ #1 - 21. Марта 2008 :: 10:37
Печать  
1. Можно юзать scoped_ptr, только тогда необходимо будет в прокси-классе явно запретить конструктор копирования и оператор присвания.
2. Если мы хотим сделать полностью независимые модули, тогда на самом деле придется делать собственный класс смарт-пойнтера.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Модульность - структура прокси-классов
Ответ #2 - 21. Марта 2008 :: 10:42
Печать  
artbear писал(а) 21. Марта 2008 :: 10:37:
1. Можно юзать scoped_ptr, только тогда необходимо будет в прокси-классе явно запретить конструктор копирования и оператор присвания.

Достаточно их не определять вообще Улыбка Тогда умолчальные реализации будут обламываться при попытке скопировать m_pImpl. scoped_ptr некопирабельный.

artbear писал(а) 21. Марта 2008 :: 10:37:
2. Если мы хотим сделать полностью независимые модули, тогда на самом деле придется делать собственный класс смарт-пойнтера.

Для "полностью независимых" вообще не важно чего мы будет использовать Улыбка Они же вообще независимы Улыбка Но мне кажется, что scoped_ptr не будет вообще меняться - потому что менять там уже особо нечего Улыбка В принципе, можно выдрать его из Буста, запихнуть в отдельный namespace и зафиксировать в SDK. Для scoped_ptr такая операция должна быть простой.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Модульность - структура прокси-классов
Ответ #3 - 21. Марта 2008 :: 14:00
Печать  
Uzhast писал(а) 21. Марта 2008 :: 10:42:
В принципе, можно выдрать его из Буста, запихнуть в отдельный namespace и зафиксировать в SDK.

Да, мне также этот вариант импонирует Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Модульность - структура прокси-классов
Ответ #4 - 21. Марта 2008 :: 14:03
Печать  
Uzhast писал(а) 21. Марта 2008 :: 09:58:
Код
Выбрать все
class RealClass {
public:
void SomeMethod () {...}
};

class ProxyClass {
boost::shared_ptr<RealClass> m_pImpl;
public:
void SomeMethod () {m_pImpl->SomeMethod ();}
};
 



Олег, надеюсь, ты говоришь о том, что в прокси-классе не должны быть инлайновые методы типа приведенного SomeMethod, иначе любая правка реального класса будет вести кучу компиляций связанных модулей, т.е. о реальном классе модули знают только, что он есть, а весь интерфейс определяется из прокси.
Это я на всякий случай уточняю Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Модульность - структура прокси-классов
Ответ #5 - 21. Марта 2008 :: 14:10
Печать  
artbear писал(а) 21. Марта 2008 :: 14:03:
Олег, надеюсь, ты говоришь о том, что в прокси-классе не должны быть инлайновые методы типа приведенного SomeMethod, иначе любая правка реального класса будет вести кучу компиляций связанных модулей, т.е. о реальном классе модули знают только, что он есть, а весь интерфейс определяется из прокси.
Это я на всякий случай уточняю Улыбка

Если эту обертку использовать в модуле, где находится основной класс для этой обертки, то все инлайновые функции в этой обертке срочно перестанут быть инлайновыми. Дело в том, что обертка экспортируется через dllexport, а в этом случае инлайн отдыхает. Хотя писать лучше конечно с использованием cpp-файла - раз инлайна все равно не будет, то нефиг создавать тормоза компиляции Улыбка Ну, а вообще, должно быть два варианта заголовков для оберток: заголовки в том модуле, где находится экспортируемый класс. И заголовки для импортирующих модулей. В этих заголовках никакой реализации уже не будет. Будем считать, что я привел пример заголовков первого типа Улыбка
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать