[C++]хочется странного

Тема в разделе "LANGS.C", создана пользователем osox, 11 ноя 2010.

  1. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Всех приветствую
    есть класс пример
    Код (Text):
    1. class someclass{
    2.     ...backgroundworker();
    3. public:
    4.     ...foregroundworker();
    5. };
    backgroundworker это служебная функция помогающая
    в реализации паблик методов типа
    клиентам вообще ее лучше не видеть
    но так как она внутри обращается к приват полям
    то пришлось тащить ее в интерфейс как приват член
    можно конечно описать как friend но все равно
    ее будет видно клиентам хочется чтоб про нее вообще не знали
    как сделать ?
    думал сделать паблик метод меняюший приват поля
    и внутри backgroundworker использовать его
    тогда backgroundworker можно было бы из интерфейса выкинуть
    но тогда появился бы новый костыль в интерфейсе и любой кому не лень этот паблик интерфейс
    заюзает и изменит
    приват поля вообщем незнаю жду ваших советов ...
    хочется чтоб backgroundworker была
    простой функцией имеющей доступ к приват полям
    и чтоб в описании интерфейса класса
    о ней вообще не упоминалось
     
  2. slayer

    slayer New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2004
    Сообщения:
    23
    Сделать интерфейс, который будете предоставлять клиентам, а в реализации городить можно что угодно. Клиенты должны использовать интерфейс, реализацию они видеть не должны
    Код (Text):
    1. struct ISomeClass
    2. {
    3.     foregroundworker();
    4.  
    5.     static ISomeClass* CreateSomeClass(...)
    6.     {
    7.          return new CSomeClass(...)
    8.     }
    9.  
    10. }
    11.  
    12. class CSomeClass : public ISomeClass
    13. {
    14.     ...backgroundworker();
    15. public:
    16.     ...foregroundworker();
    17. };
     
  3. Sasha7b9

    Sasha7b9 New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2010
    Сообщения:
    105
    Много хочешь. Может, уважительней к потенциальным помощникам для начала отнестись?
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
  5. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    ... здесь было много плохих слов ...
    [modnote=TermoSINteZ]Предупреждение. Еще раз и в бан. Уважайте участников форума.[/modnote]
     
  6. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    osox
    Тебе пояснили уже "pimpl" , то что ты хочешь это и идиома называется "Pointer to implementation". можно так:


    lib1.hpp:

    Код (Text):
    1. class MySuperPuperLib {
    2. public:
    3.   MySuperPuperLib();
    4.   ~MySuperPuperLib();
    5. private:
    6.   class MySuperPuperLibHelper;
    7.   typedef   std::auto_ptr<MySuperPuperLibHelper>   MySuperPuperLibHelperPtr_t;
    8.   MySuperPuperLibHelperPtr_t  _helper;
    9. };
    lib1.cpp:
    Код (Text):
    1. #include <std.hpp>
    2.  
    3. class MySuperPuperLib::MySuperPuperLibHelper {
    4. // тут кишки хэлпера
    5. };
    6.  
    7. MySuperPuperLib::MySuperPuperLib()
    8.   : _helper(new MySuperPuperLibHelper)
    9. {
    10. }
    11.  
    12. MySuperPuperLib::~MySuperPuperLib()
    13. {
    14. }
    примерно как-то так. главная мысль "деструктор и конструктор основного класса, должны видеть декларацию класса-хелпера, иначе как им знать как создавать и как убивать?"
     
  7. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    а так нормально ?
    файл интерфейса
    yyk.h
    Код (Text):
    1. class someclass{
    2.     int fd;
    3. public:
    4.     void foregroundworker();
    5. };
    файл реализации
    yyk.cpp
    Код (Text):
    1. class someclass{
    2.     int fd;
    3.     void backgroundworker(int c){fd=c;}
    4. public:
    5.     void foregroundworker();
    6. };
    7. void someclass::foregroundworker(){
    8.     this->backgroundworker(0x111);
    9. }
    драйвер
    main.cpp
    Код (Text):
    1. #include "yyk.h"
    2.  
    3. int main(){
    4.     someclass o;
    5.     o.foregroundworker();
    6. }
    вроде то что нужно можно ли так ?
    делает оно то что мне нужно
    но это не похоже на pimpl
     
  8. Sasha7b9

    Sasha7b9 New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2010
    Сообщения:
    105
    osox
    Хотя помощников, похоже, твой стиль вполне устраивает)
    Что ж, удачи. Продолжай в том же духе.
     
  9. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    угу а знаеш почему ? потому что среди них
    ты один мудaк

    [modnote=Great]А ведь предупреждали.([/modnote]
     
  10. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    общий смысл таков ?
    lib.h
    Код (Text):
    1. class sc{
    2.     class hlp;
    3.     hlp *p;
    4. public:
    5.     int pub;
    6.     sc(int c);
    7.     ~sc();
    8.     void print();
    9. };
    lib.cpp
    Код (Text):
    1. #include "lib.h"
    2.  
    3. class sc::hlp{
    4. public:
    5.     hlp(int c):f(c){}
    6.     int f;
    7.     void back(sc *r){
    8.         puts("back");
    9.         this->f = 789;
    10.         r->pub = 890;
    11.     }
    12. };
    13.  
    14. sc::sc(int c):p(new hlp(c)){}
    15. sc::~sc(){delete p;}
    16.  
    17. void sc::print(){
    18.     printf("%x\n", this->p->f);
    19.     this->p->back(this);
    20. }
    main.cpp
    Код (Text):
    1. #include "lib.h"
    2.  
    3. int main(){
    4.     sc c(0x777);
    5.     c.print();
    6. }
     
  11. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    А ещё можно так.
    .H файл:
    Код (Text):
    1. struct tag_TDATACLASS_MEMBERS;
    2.  
    3. class TDataClass
    4. {
    5.     public:
    6.         TDataClass ();
    7.         virtual ~TDataClass ();
    8.         //
    9.         // Interface for consumer of this object
    10.         //
    11.         HRESULT     PerformAction1 ();
    12.         HRESULT     PerformAction2 ();
    13.         HRESULT     PerformAction3 ();
    14.  
    15.     private:
    16.         tag_TDATACLASS_MEMBERS*     m_pMembers;
    17. };
    .CPP файл:
    Код (Text):
    1. #include <windows.h>
    2. #include "TDataClass.h"
    3.  
    4. typedef struct tag_TDATACLASS_MEMBERS
    5. {
    6.     HANDLE  Handle;
    7.     UINT    Flags;
    8.     WCHAR   Path [MAX_PATH];
    9. }
    10. TDATACLASS_MEMBERS;
    11.  
    12. static int _Helper1 (TDATACLASS_MEMBERS& data);
    13. static int _Helper2 (TDATACLASS_MEMBERS& data);
    14. static int _Helper3 (TDATACLASS_MEMBERS& data);
    15.  
    16. TDataClass::TDataClass ()
    17. {
    18.     m_pMembers = (TDATACLASS_MEMBERS*) calloc (1, sizeof (TDATACLASS_MEMBERS));
    19. }
    20.  
    21. TDataClass::~TDataClass ()
    22. {
    23.     free (m_pMembers);
    24. }
    25.  
    26. static int _Helper1 (TDATACLASS_MEMBERS& data)
    27. {
    28.     if (data.Flags & 1)
    29.     {
    30.         _Helper3 (data);
    31.     }
    32.     return 0;
    33. }
    34.  
    35. static int _Helper2 (TDATACLASS_MEMBERS& data)
    36. {
    37.     data.Handle = ::HeapCreate (0, 0, 0);
    38.     return 0;
    39. }
    40.  
    41. static int _Helper3 (TDATACLASS_MEMBERS& data)
    42. {
    43.     ::SetCurrentDirectory (data.Path);
    44.     return 0;
    45. }
    46.  
    47. HRESULT TDataClass::PerformAction1 ()
    48. {
    49.     //...
    50.     _Helper1 (*m_pMembers);
    51.     //...
    52.     return 0;
    53. }
    54.  
    55. HRESULT TDataClass::PerformAction2 ()
    56. {
    57.     //...
    58.     _Helper2 (*m_pMembers);
    59.     //...
    60.     return 0;
    61. }
    62.  
    63. HRESULT TDataClass::PerformAction3 ()
    64. {
    65.     //...
    66.     _Helper3 (*m_pMembers);
    67.     //...
    68.     return 0;
    69. }
    Удобно для сохранения/восстановления данных класса - одна операция чтения/записи на всю структуру вместо по-элементного доступа.

    Минус: достать данные из адреса требует дополнительной загрузки регистра -- хотя зависит от компилятора. Полностью оптимизированный код может и не иметь такой проблемы. Зато тот, кто пользуется классом не знает ничего о вспомогательных функциях или даже какие данные этот класс содержит.
     
  12. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    AsmGuru62
    Ваш вариант без интелектуального указателя, а правила хорошего тона диктуют моду перекладывать убийство динимеческих объектов на не механизмы std::auto_ptr, std::tr1_shared_ptr, etc . То есть программист не должен задаваться вопросом "А освобождается ли у меня ресурс?". Об этом еще дядюшка Майерс неоднократно заявлял )
     
  13. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    EvilsInterrupt
    Если уж решил "умничать", то признай, что твой пример тоже не удачный. auto_ptr не может корректно удалять incomplete type. shared_ptr нужен.
     
  14. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    censored
    Вопрос был каков? "хочется странного", т.е. человеку нужно направление, так? А значит примера до полной компиляции можно и не давать!
    ну и второе!!! Походу ты адски слепой человек, твои слова:
    >>корректно удалять incomplete type. shared_ptr нужен.
    можно было и не писать, если бы ты ВНИМАТЕЛЬНО прочитал мой пост и увидел бы:
    А тут, есть шаред_птр!!!

    Разуй глаза в след. раз, когда будешь чтото критиковать! и включай голову
     
  15. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Топик стартеру не нужен классический pImpl, т.к. прятать нужно только методы, а не данные.
    Достаточно будет:
    Код (Text):
    1. // C.h
    2. class C
    3. {
    4.     int f1();
    5.  
    6.     struct Impl;
    7. public:
    8.     int f2();
    9.  
    10. };
    11.  
    12.  
    13.  
    14. // C.cpp
    15.  
    16. struct C::Impl
    17. {
    18.     static int f2_hlpr(C *pThis)
    19.     {
    20.         return pThis->f1();
    21.     }
    22. };
    23.  
    24. int C::f2()
    25. {
    26.     return Impl::f2_hlpr(this);
    27. }
     
  16. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    EvilsInterrupt
    Деструктор всегда вызовется.
     
  17. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    >>Деструктор всегда вызовется.
    Не всегда. К примеру если во время работы конструктора будет сгенерировано исключение, то деструктор нихрена не вызовется!
     
  18. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    EvilsInterrupt
    В конструкторе сложный код не надо писать - чтобы не было исключений.
    Выделить память и почистить переменные - и если это уже "падает", тогда архитектурные
    замыслы уже не нужны.
     
  19. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    AsmGuru62
    Исключения в С++ - это не только результат "падений", но и способ обработки логических ошибок.
    Фактически, синхронный выброс исключения (через throw) - это штатный способ вернуть ошибку из конструктора.
     
  20. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    green

    Языковые исключения C++ - это вообще ни разу не результат падений :)