На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Абстрактный базовый класс Display. , void * давить или нет?
    Хочу написать класс-оболочку для представления дисплея. Для этого собираюсь создать абстрактный базовый класс Display, в котором будут чисто вирт. ф-ции line(), circle() и пр. Далее мечтаю наследовать от него DisplayBuilder, DisplayVisuallCpp так, чтобы мою прогу, которая будет использовать этот класс дря рисования, можно было запросто перенести из Builder'а в Visuall Cpp (т.к. рисовать я буду через указатель на базовый класс проблем не будет, ведь остальной код не изменится). Так вот. Вопрос. Как мне объявить конструктор в Display? Ведь для DisplayBuilder переменной-членом будет CDC *m_cdc, а для DisplayVisuallCpp TCanvas *m_canvas. Пока у меня только одна идея Display( void *p ). Но это, по-моему, не очень модно. Вот и хочу узнать, что думают остальные по этому поводу.


    Заранее спасибо.
      А если вспомнить, что Canvas и CDC работает через DC - контекст устройства в WinAPI, то начинает вырисовываться несколько другая архитектура.
        Цитата Flex_Ferrum,9.01.04, 14:30
        А если вспомнить, что Canvas и CDC работает через DC - контекст устройства в WinAPI, то начинает вырисовываться несколько другая архитектура.

        Нет. Позвольте. Вся прелесть-то в том, что в первом случае я смогу делать так m_canvas-> м далее вываливается список доступных ф-ций-членов. Во втором случае тоже понятно m_cdc и другой список ф-ций. Если я перейду на Win API, то проблемы бы этой не возникло. Поэтому всё же хочу узнать ваше мнение по поводу void *.
          А если сделать инерфейсныйкласс-прослойку?
          ЗВ
          Надеюсь понятно выразился :D
          ЗЗЫ
          Ничего не знаяю о Canvas и его отличаях от CDC поэтому с реализацией помочь не могу
            Цитата dimedrol,9.01.04, 16:45
            А если сделать инерфейсныйкласс-прослойку?
            ЗВ
            Надеюсь понятно выразился :D
            ЗЗЫ
            Ничего не знаяю о Canvas и его отличаях от CDC поэтому с реализацией помочь не могу

            Что такое инерфейсный класс-прослойка? Хочу детали.
              ExpandedWrap disabled
                 
                class CBaseDC
                {
                public:
                    virtual  ~CBaseDC(){}
                    virtual  InitDC()=0;
                    virtual BeginPaint()=0;
                    virtual  EndPaint()=0;
                    //остальные услуги, которые тебе требуються
                };

              Класс обертка над DC/Canvas. Я просто не знаю как работать с Canvas и насколько он отличаеться от DC.
              Сообщение отредактировано: dimedrol -
                Я бы тогда предложил бы условную компиляцию:
                ExpandedWrap disabled
                   
                  class Display
                  {
                  //...
                  public:
                  #ifdef __BORLANDC__
                  Display(TCanvas* canvas) {;}
                  #else
                  Display(CDC* dc) {;}
                  #endif
                  //...
                  };
                  Цитата Flex_Ferrum @ 10.01.04, 16:50
                  Я бы тогда предложил бы условную компиляцию:

                  А если вдруг понадобится какой-нибудь другой контекст. Добавить? Придется дописывать и перекомпелировать кучу кода
                  Раз используеться ООП, то в том же стиле и надо писать. Наскоко я понямаю любые фокусы с макросами не приветствуються
                    Цитата
                    dimedrol, 11.01.04, 20:04
                    А если вдруг понадобится какой-нибудь другой контекст. Добавить? Придется дописывать и перекомпелировать кучу кода
                    Раз используеться ООП, то в том же стиле и надо писать. Наскоко я понямаю любые фокусы с макросами не приветствуються

                    Вот и попробуй :)) В ряде случаев уж лучше макрос, чем void*.
                      а почему нельзя использовать два конструктора ?

                      Display( CDC *cdc );
                      Display( TCanvas *canvas );

                      а вот выше использовать ifdef

                      #ifdef __BORLANDC__
                      class CDC{ };
                      #else
                      class TCanvas{ };
                      #endif
                        Вопрос решил. Всё дело в том, что я забыл, что конструкторы не наследуются и, соответственно, проблема отпала. Правильный вариант:

                        ExpandedWrap disabled
                           
                          /**
                           *  Абстрактный базовый класс, который предоставляет открытый
                           *  интерфейс для конкретных реализаций дисплея.
                           */
                          class Display {
                           
                            public:
                           
                            /**
                             *  Рисует линию.
                             *  @param x1 абсцисса первой точки
                             *  @param y1 ордината первой точки
                             *  @param x2 абсцисса второй точки
                             *  @param y2 ордината второй точки
                             */
                              virtual void line( int x1, int y1, int x2, int y2 ) = 0;
                           
                          }; // class Display
                           
                          /**
                           *  Дисплей для Builder'а.
                           */
                          class DisplayBuilder: public Display {
                           
                            public:
                           
                            /**
                             *  Конструктор.
                             *  @param pCanvas указатель на объект класса TCanvas
                             */    
                              DisplayBuilder( TCanvas *pCanvas ) :
                                m_canvas( pCanvas )  
                              {}
                           
                            /**
                             *  Рисует линию.
                             *  @param x1 абсцисса первой точки
                             *  @param y1 ордината первой точки
                             *  @param x2 абсцисса второй точки
                             *  @param y2 ордината второй точки
                             */
                              void line( int x1, int y1, int x2, int y2 ) {
                                m_canvas->MoveTo( x1, y1 );
                                m_canvas->LineTo( x2, y2 );
                              }
                           
                            protected:
                           
                            /**
                             *  Указатель на объект класса TCanvas,
                             *  посредством которого будет осуществляться рисование.
                             */
                              TCanvas *m_canvas;
                           
                          }; // class DisplayBuilder
                           
                          /**
                           *  Дисплей для Visual C++.
                           */
                          class DisplayVisualCpp: public Display {
                           
                            public:
                           
                            /**
                             *  Конструктор.
                             *  @param pDC указатель на объект класса CDC
                             */    
                              DisplayVisualCpp( CDC *pDC ) :
                                m_dc( pDC )  
                              {}
                           
                            /**
                             *  Рисует линию.
                             *  @param x1 абсцисса первой точки
                             *  @param y1 ордината первой точки
                             *  @param x2 абсцисса второй точки
                             *  @param y2 ордината второй точки
                             */
                              void line( int x1, int y1, int x2, int y2 ) {
                                m_dc->MoveTo( x1, x2 );
                                m_dc->LineTo( x2, y2 );
                              }
                           
                            protected:
                           
                            /**
                             *  Указатель на объект класса CDC,
                             *  посредством которого будет осуществляться рисование.
                             */
                              CDC *m_dc;
                           
                          }; // class DisplayVisualCpp


                        Далее в программе:
                        [/CODE]
                        CWnd *pWnd = GetDlgItem( IDC_STATIC_CANVAS1 );
                        CDC *pCanvasDC = pWnd->GetDC();

                        ///////////////////////////////////////////////
                        pWnd->Invalidate();
                        pWnd->UpdateWindow();
                        ///////////////////////////////////////////////

                        DisplayVisualCpp disp1( pCanvasDC );

                        pWnd->ReleaseDC( pCanvasDC );
                        [/CODE]

                        Добавлено в :
                        Ё-моё лажанулся с [CODE]
                          А можно было так:
                          ExpandedWrap disabled
                             
                            class DisplayBase
                            {
                            public:
                            Display(HDC hdc) : m_hDC(hdc) {;}
                            void line(int x1, int y1, int x2, int y2)
                            {
                               POINT pnt;
                               MoveToEx(m_hDC, x1, y1, &pnt);
                               LineTo(m_hDC, x1, y2);
                            }
                            private:
                            HDC m_hDC;
                            };
                             
                            class Display : public DisplayBase
                            {
                            public:
                            #ifdef __BORLANDC__
                            Display(TCanvas* canvas) : DisplayBase(canvas->Handle) {;}
                            #else
                            Display(CDC* dc) : DislpayBase(dc->GetSaveHdc()) {;}
                            #endif
                            };
                             
                            // Далее в программе
                            CWnd *pWnd = GetDlgItem( IDC_STATIC_CANVAS1 );
                            CDC *pCanvasDC = pWnd->GetDC();
                             
                            ///////////////////////////////////////////////
                            pWnd->Invalidate();
                            pWnd->UpdateWindow();
                            ///////////////////////////////////////////////
                             
                            Display disp1( pCanvasDC );
                             
                            pWnd->ReleaseDC( pCanvasDC );
                          Сообщение отредактировано: Flex_Ferrum -
                            Согласен, что можно. Только вот условная компиляция немного противоречит принципамм ООП. В этом плане полностью согласен с dimedrol.

                            Меня сейчас интересует другое. Не стоит ли GetDC() и ReleaseDC() засунуть внутрь DisplayVisualCpp? Параметром конструктора ведь вполне может быть и идентификатор static'а, на кототом собираюсь рисовать. Можно ли GetDC() и ReleaseDC() вызывать в конструкторе и деструкторе соответственно? Или же не стоит? Что-то слышал про несовсем обычную природу того указателя, что возвращает GetDC(). Его вроде бы нельзя надолго сохранять. Это так? Или я глючу.
                              Цитата
                              poi, 12.01.04, 14:32
                              Согласен, что можно. Только вот условная компиляция немного противоречит принципамм ООП. В этом плане полностью согласен с dimedrol.

                              Но не тогда, когда тебе нужна кроссплатформенность. Я бы на твоем месте не стал приностить простоту класса и итогового дизайна в жертву этому принципу. Или тебе хочется писать вдвое больше кода?

                              По поводу вопроса - можно. И это будет соответствовать принципу ООП "Объявление есть инциализация".
                              Сообщение отредактировано: Flex_Ferrum -
                                Цитата Flex_Ferrum @ 12.01.04, 11:42
                                Но не тогда, когда тебе нужна кроссплатформенность. Я бы на твоем месте не стал приностить простоту класса и итогового дизайна в жертву этому принципу. Или тебе хочется писать вдвое больше кода?

                                По поводу вопроса - можно. И это будет соответствовать принципу ООП "Объявление есть инциализация".

                                Мне не нужна кроссплатформенность в её стандартном понимании! Всё это - исследовательская работа. И мне нужно именно ООП. А за ответ большое спасибо.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0529 ]   [ 16 queries used ]   [ Generated: 2.05.24, 12:54 GMT ]