Russian Qt Forum
Ноябрь 22, 2024, 19:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] правильная реализация паттерна Pimpl  (Прочитано 7994 раз)
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« : Июнь 06, 2012, 00:40 »

Здравствуйте. Первый раз в жизни пришлось использовать паттерн Pimpl (pointer to implementation) для того, чтобы код имел нормальный вид (перед этим хедер был написан через #ifdef Q_WS_MACX #else #endif и просто ужасен, могу показать Улыбающийся ). Покритикуйте пожалуйста - какие ошибки допущены, как сделать лучше.

Класс реализует простенький месседжбокс с чекбоксом и кнопками да/нет. В мак ос это просто обертка над NSAlert, а на других платформах - полноценный QDialog.

Вот тут прикреплён окончательный вариант реализации: http://www.prog.org.ru/index.php?topic=22129.msg154409#msg154409
« Последнее редактирование: Июль 25, 2012, 13:55 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #1 : Июнь 06, 2012, 08:06 »

Здравствуйте. Первый раз в жизни пришлось использовать паттерн Pimpl (pointer to implementation) для того, чтобы код имел нормальный вид (перед этим хедер был написан через #ifdef Q_WS_MACX #else #endif и просто ужасен, могу показать Улыбающийся ). Покритикуйте пожалуйста - какие ошибки допущены, как сделать лучше.

Класс реализует простенький месседжбокс с чекбоксом и кнопками да/нет. В мак ос это просто обертка над NSAlert, а на других платформах - полноценный QDialog.
Вроде все хорошо, но в самом Qt немного другая реализация. Вот здесь об этом подробно описано.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #2 : Июнь 06, 2012, 08:25 »

да, эту статью я читал, но для простенького случая там слишком много ненужного кода Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #3 : Июнь 06, 2012, 08:58 »

Неправильно всё. Нахрена там вообще виртуальность?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Июнь 06, 2012, 09:15 »

не придумал как по-другому сделать один из классов наследником QDialog при одном и том же интерфейсе
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #5 : Июнь 06, 2012, 09:38 »

Интерфейсом является сам класс. Наследования там не надо. Вы просто реализуете его ф-ии под конкретную платформу в отдельном файле. Если есть платформонезависимые ф-ии, реализуете их в общем .cpp. Линковщик сам подцепит нужную имплементацию.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июнь 06, 2012, 12:19 »

Лучше смотрится так

Код
C++ (Qt)
class MessageCheckBoxImpl;
 
class MessageCheckBox
{
public:
   MessageCheckBox(const QString &text, const QString &checkboxText, QWidget *parent = 0);
   virtual ~MessageCheckBox();
 
   void setChecked(bool checked);
   bool isChecked();
 
   int exec();
 
private:
   MessageCheckBoxImpl * mImpl;
};
 
А потом 2 файла cpp для каждой из платформ. Да, придется в каждом написать напр MessageCheckBox::setChecked, но это лучше чем размазывать в хедере. Др словами более "идейно" не светить никаких деталей MessageCheckBoxImpl
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #7 : Июнь 06, 2012, 14:46 »

спасибо, переделал (пркрепил к посту). но напрягает необходимость написания одной и той же реализации конструктора в обоих файлах реализаций:
Код
C++ (Qt)
MessageCheckBox::MessageCheckBox(const QString &text, const QString &checkboxText, QWidget *parent /*= 0*/) : _impl(new MessageCheckBoxImpl(text, checkboxText, parent)) {}
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 06, 2012, 15:22 »

спасибо, переделал (пркрепил к посту). но напрягает необходимость написания одной и той же реализации конструктора в обоих файлах реализаций:
Код
C++ (Qt)
MessageCheckBox::MessageCheckBox(const QString &text, const QString &checkboxText, QWidget *parent /*= 0*/) : _impl(new MessageCheckBoxImpl(text, checkboxText, parent)) {}
Не вижу напряга, т.к. конструктор на платформу завязан. Вот если бы образовались методы которым не нужен impl (т.е. работают на уровне setChecked), то можно отнаследоваться (наследник уже платформо-независим)
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #9 : Июнь 06, 2012, 17:59 »

в данном случае конструктор одинаков и там и там, потому получается дублирование кода Улыбающийся может в таком случае лучше сделать MessageCheckBoxImpl структурой с нужными полями без всяких методов и конструкторов, а текущий конструктор MessageCheckBoxImpl перенести в конструктор MessageCheckBox?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Июнь 06, 2012, 18:17 »

в данном случае конструктор одинаков и там и там, потому получается дублирование кода Улыбающийся может в таком случае лучше сделать MessageCheckBoxImpl структурой с нужными полями без всяких методов и конструкторов, а текущий конструктор MessageCheckBoxImpl перенести в конструктор MessageCheckBox?
Одинаков "формально", по написанию (и это не надолго). А на деле тело конструктора знает платформу, поэтому должно быть 2 тела, каждое в своем cpp. Думайте проще: отот impl должен быть в хедере "совсем бестелесным", с него извне ничего не взять даже если захотеть. Не надо бояться разумного дублирования, в конце-концов делегирование - тоже дубляж
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.119 секунд. Запросов: 22.