Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

Открыть новую тему     Написать ответ в эту тему

Crazy_Shrike



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Вопросы по программированию на C/С++

 
  • Справочники, книги
  • Выбор IDE (среды программирования)
     
    Постарайтесь дать как можно больше информации о возникшей проблеме - это в конце концов в ваших же интересах чтобы вам помогли.

    Решения конкретных задач собираются и обсуждаются в теме Задачи по C/С++ .

    Прежде чем просить помощи в задании...
    Если позарез надо и вы даже готовы заплатить

    Как правильно задавать вопросы, если вы хотите получить ответ.

    Полезные ссылки:
    C++(eng)

  • Всего записей: 241 | Зарегистр. 25-03-2004 | Отправлено: 13:37 06-05-2004 | Исправлено: AZJIO, 19:45 12-05-2014
    TeXpert



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    Можно так: указатели obj1, obj2,..., objN заносишь в массив, а с массивом всё компактней в цикле


    Цитата:
    А это точно? Система не завершит работу программы? Или могут быть и такие системы, которые при этом тупо убьют процесс?

    Вот не могу знать это для всех систем).


    ----------
    Майкудук, Пришахтинск не предлагать!:)
    А на Пирогова приходит снова весенний гомон...

    Всего записей: 3604 | Зарегистр. 08-02-2003 | Отправлено: 04:23 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Сам по себе goto неплох, но вот

    В принципе, я тоже начинаю так думать. В этих 2-х подходах есть такой момент: первый повторяет много одного и того-же кода - free(objI) повторяется много раз, а второй более компактный по размеру, но производит много лишних сравнений (if (objI) повторяется сначала перед goto, а потом - после _err), т.е., проигрывает по скорости, хотя, все эти лишние сравнения делаются только в том случае, если произошла ошибка при инициализации одного из объектов, а в таком случае, чаще всего, скорость уже некритична. Но goto - некрасивый подход, ИМХО.
    Вот я и думаю, может, найдется третий, более элегантный вариант?
     

    Цитата:
    А где malloc?  

    malloc вызывается в функциях APIfunc1...APIfuncN(). На самом деле, это и не совсем malloс, так как возвращаются не указатели на объекты, а указатели на интерфейсы (т.е., например, IWebBrowser2* obj1), и это не совсем free, вызывается obj1->Release(), но суть от этого не меняется - в любом случае в конце нужно вызывать какую-то функцию, чтобы освободить эти объекты.
     
    Кстати, на самом деле я еще немного протупил: метка _err должна стоять до return SOMETHING (сейчас опять исправил исходный пост), иначе все промежуточные объекты останутся в памяти. В некоторых языках (в Делфи, вроде бы) есть конструкция try ... catch ... finally, и как раз в блоке finally и выполняется работа по уничтожению всего, что должно быть уничтожено в любом случае, независимо от того, возникла ошибка или нет. Но в С++, почему-то, такой возможности не предусмотрели. Жаль.
     
    Добавлено:

    Цитата:
    Можно так: указатели obj1, obj2,..., objN заносишь в массив, а с массивом всё компактней в цикле

    Дык для инициализации каждого объекта вызывается своя функция, и все объекты при этом разнотипные.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 04:32 26-01-2007 | Исправлено: xdude, 04:37 26-01-2007
    TeXpert



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    ...malloc вызывается в функциях APIfunc1...APIfuncN()

    Я так и подозревал.
     

    Цитата:
     некоторых языках (в Делфи, вроде бы) есть конструкция try ... catch ... finally, и как раз в блоке finally и выполняется работа по уничтожению всего, что должно быть уничтожено в любом случае, независимо от того, возникла ошибка или нет. Но в С++, почему-то, такой возможности не предусмотрели. Жаль.

    Ну почему нету? Если ты делаешь в Windows, то там всё есть, насколько помню. Ты в Рихтера заглядывал?
     

    Цитата:
    Дык для инициализации каждого объекта вызывается своя функция

    Ну так имена функций -- тоже в массы (массив))!
     
    Добавлено:
    Вот выдержка из FAQ:

    Цитата:
     
    В:    Если есть указатель (char *) на    имя функции в виде стринга, то как
        эту функцию вызвать?
     
    О:    Наиболее прямолинейный путь - создание таблицы имен и соответствующих
        им указателей:
     
              int function1(), function2();
     
              struct {char *name; int (*funcptr)();    } symtab[] =
                  {
                  "function1",      function1,
                  "function2",      function2,
                  };
     
        Ну а теперь нужно поискать в таблице нужное имя    и вызвать функцию,
        используя связанный с именем указатель.
     


    ----------
    Майкудук, Пришахтинск не предлагать!:)
    А на Пирогова приходит снова весенний гомон...

    Всего записей: 3604 | Зарегистр. 08-02-2003 | Отправлено: 04:43 26-01-2007 | Исправлено: TeXpert, 05:08 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Ну так имена функций -- тоже в массы

    Ну, вряд ли это добавит читабельности коду, да и не решит проблему высвобождения промежуточных объектов.

    Цитата:
    Ну почему нету? Если ты делаешь в Windows, то там всё есть, насколько помню. Ты в Рихтера заглядывал?

    В том-то и дело, что только у виндовса это и есть. "Microsoft specific", блин А я пишу кросс-платформенные приложения.
     
    Добавлено:

    Цитата:
    Ну а теперь нужно поискать в таблице нужное имя    и вызвать функцию,  
        используя связанный с именем указатель.  

    А это уж совсем из области интерпретаторов Короче, чтобы нормально писать на С/С++ - нужно написать интерпретатор какого-нибуть скриптового языка. и писать на нём

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 05:08 26-01-2007
    TeXpert



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    В том-то и дело, что только у виндовса это и есть. "Microsoft specific", блин

    Ты непоследователен. Тогда зачем плач по Делфям?)
     
    Добавлено:

    Цитата:
    А это уж совсем из области интерпретаторов

    Да нет, это из FAQ по С/С++, зря ты злобствуешь.


    ----------
    Майкудук, Пришахтинск не предлагать!:)
    А на Пирогова приходит снова весенний гомон...

    Всего записей: 3604 | Зарегистр. 08-02-2003 | Отправлено: 05:11 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Ты непоследователен. Тогда зачем плач по Делфям?

    Как раз наоборот последователен: плачу, что в винде и в делфях (недоступных мне) это реализовано, а в стандартном С++ (таком близком и родном) - нет
     
    Добавлено:

    Цитата:
    зря ты злобствуешь.

    Да я не злобствую Просто искать указатель на функцию по её имени в таблице имён - это как раз одна из задач интерпретатора Я когда-то пытался свой скриптовый язык придумать от нечего делать, приходилось такое писать.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 05:17 26-01-2007
    Mickey_from_nsk

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Есть более элегантный способ освобождать память при выходе из функции (при определенных условиях) - использование вместо malloc функции alloca, которая выделяет память на стеке. Я думаю понятны и плюсы и минусы этого метода.
    Второй способ автоматического удаления памяти - auto_ptr или им подобная концепция. То есть, использование специальных объектов, которые при разрушении уничтожают память, если она была выделена.

    Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 07:40 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Есть функция:
    typedef void* (*callback_t) (void*);
    int somefunc(int flags, callback_t callback,void* callback_param);
    и есть класс Someclass
    {
      ...
      virtual void *somemethod();
    };
     
    Есть ли возможность передать метод Someclass::somemethod в функцию somefunc? somefunc(flags,(callback_t)this->somemethod,this) не срабатывает, другое всё тоже перепробовал. Пришлось создать вспомогательную функцию, которой передается указатель на объект класса, и которая вызывает ((Someclass*)ptr)->somemethod();
    А напрямую никак нельзя?
     
    Добавлено:

    Цитата:
    malloc функции alloca

    Не выйдет, память выделяю не я, а API-функции.

    Цитата:
    Второй способ автоматического удаления памяти - auto_ptr или им подобная концепция.

    Опять же не выйдет:

    Цитата:
    На самом деле, это и не совсем malloс, так как возвращаются не указатели на объекты, а указатели на интерфейсы (т.е., например, IWebBrowser2* obj1), и это не совсем free, вызывается obj1->Release(),

    Если писать что-то типа auto_ptr - то можно замучаться, така как:

    Цитата:
    для инициализации каждого объекта вызывается своя функция, и все объекты при этом разнотипные.

    Для освобождения, соответственно, тоже разные функции. Т.е., например, некоторые объекты освобождаются с помощью LocalFree(obj), некоторые - GlobalFree(obj) или HeapFree(obj), другие - с помощью obj->Release(), некоторые - это даже на объекты, а системные хендлы (HANDLE, HMODULE и т.д.), для одних надо вызывать FreeLibrary(obj), для других - CloseHandle(obj) ну и т.д., т.е., автоматика тут не прокатит, нужен просто наиболее оптимальный стиль написания кода.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 07:45 26-01-2007 | Исправлено: xdude, 07:58 26-01-2007
    Mickey_from_nsk

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude
    Хе-хе... В свое время я покувыркался с этим изрядно. Пока не набрел на оператор ->*. Решение заковыристое, но есть. Там все сводится к тому, что надо правильно объявить прототип callback-метода.

    Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 07:57 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Пока не набрел на оператор ->*.  

    Ну опять-таки, так как объекты все разнотипные - то запарюсь я писать для каждого отдельного типа темплейт авто-класса. Или можно, чтобы этот класс ещё и выбирал автоматом, какую функцию использовать: GlobalFree, LocalFree, free, delete, CloseHandle, FreeLibrary, и сам выискивал другую подходящуу, если такой функции в его списке нет?  
     
    Добавлено:

    Цитата:
    правильно объявить прототип callback-метода.

    А, то есть прототип объявляется при объявлении переменной? Ну все равно, некоторые функции еще несколько дополнительных параметров просят, с этим как быть? Или вот оператор delete? Хотя, в таком случае можно и auto_ptr использовать.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 08:01 26-01-2007 | Исправлено: xdude, 08:01 26-01-2007
    Mickey_from_nsk

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    А, то есть прототип объявляется при объявлении переменной?  

    Нет, при объявлении функции. Потом нужный метод приводится к типу прототипа.

    Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 10:24 26-01-2007
    RedLord

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude
     

    Цитата:
    и как раз в блоке finally и выполняется работа по уничтожению всего

     
    в плюсах есть железная идиома: захват ресурса -есть инициализация.
    auto_ptr тому пример.
     

    Цитата:
    некоторые - GlobalFree(obj) или HeapFree(obj), другие - с помощью obj->Release(),

     
    посмотри в  сторону shared_ptr boost'a.
    там есть возможность указать функцию освобождения.

    Всего записей: 730 | Зарегистр. 05-03-2004 | Отправлено: 12:52 26-01-2007
    Mickey_from_nsk

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    RedLord

    Цитата:
    посмотри в  сторону shared_ptr boost'a.  
    там есть возможность указать функцию освобождения.

    Поддерживаю.
    Вообще, написать класс-освобождатель - очень просто. Единственное что - это надо определиться какого типа освобождатель из API использовать. Для этого, думаю, пойдет концепция стратегий.

    Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 13:42 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Ну, с классом-освобождателем, теперь, я думаю разберусь Всем спасибо за советы.
    Осталось несколько вопросов, ответа на которые так и не прозвучало, а хотелось бы

    Цитата:
    Есть функция:  
    typedef void* (*callback_t) (void*);  
    int somefunc(int flags, callback_t callback,void* callback_param);  
    и есть класс Someclass  
    {  
      ...  
      virtual void *somemethod();  
    };  
     
    Есть ли возможность передать указатель метод Someclass::somemethod в функцию somefunc? somefunc(flags,(callback_t)this->somemethod,this) не срабатывает, другое всё тоже перепробовал. Пришлось создать вспомогательную функцию, которой передается указатель на объект класса, и которая вызывает ((Someclass*)ptr)->somemethod();  
    А напрямую никак нельзя?  

     
    И еще: как лучше/эффективней/удобней перехватывать эксепшены: для каждой функции в отдельности, или для серии функций?

    Код:
     
    try
    {
      ...
      func1(...);
      ...
    }
    catch (e1) { ... }
    catch (e2) { ... };
    ...
    try
    {
      ...
      func2(...);
      ...
    }
    catch (e3) { ... }
    catch (e4) { ... };
    и т.д.
     

    или так:

    Код:
     
    try
    {
      ...
      func1(...);
      ...
      func2(...);
      ...
      func3(...);
      ...
    }
    catch (e1) { ... }
    catch (e2) { ... }
    catch (e3) { ... }
    catch (e4) { ... };
     
     


    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 23:52 26-01-2007
    RedLord

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    Есть функция:  
    typedef void* (*callback_t) (void*);  
    int somefunc(int flags, callback_t callback,void* callback_param);  
    и есть класс Someclass  
    {  
      ...  
      virtual void *somemethod();  
    };  
       
    Есть ли возможность передать указатель метод Someclass::somemethod в функцию somefunc? somefunc(flags,(callback_t)this->somemethod,this) не срабатывает, другое всё тоже перепробовал. Пришлось создать вспомогательную функцию, которой передается указатель на объект класса, и которая вызывает ((Someclass*)ptr)->somemethod();  
    А напрямую никак нельзя?  

     
    typedef void* (*callback_t) ();  - это указатель на _не_ мемберную функцию и естественно, мембер класса не пройдет
     
    typedef void* (Someclass::*callback_t) () - указатель  на мембер класса
     
    struct Someclass  
    {  
            virtual void* somemethod()  // 1
            {
                return 0;
            }
            virtual void* somemethod(void*) //2
            {
                return 0;
            }
    };  
        typedef void* (Someclass::*fn)();
        fn f = &Someclass::somemethod;
        Someclass ss;
        (ss.*f)();  // вызов 1
     
        typedef void* (Someclass::*fn1)(void*);
        fn1 f1 = &Someclass::somemethod;
        (ss.*f1)(0); // вызов 2
     
    почитай Страуструпа, посмотри в  сторону  опять таки  boost: bind  и  function  тебе помогут

    Всего записей: 730 | Зарегистр. 05-03-2004 | Отправлено: 02:19 27-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    typedef void* (*callback_t) ();  - это указатель на _не_ мемберную функцию и естественно, мембер класса не пройдет

    Дык это я знаю. Это тип, и функция, в которую он передается, определены в API, поэтому другой тип я туда передать не могу, переопределить прототип функции - тоже. По сути, ведь мемберская функция вполне подошла бы, так как в мемберскую функцию передаётся указатель на this вместо void*, просто компилятор не пропускает такой каст. Хотя, если это сделать через ассемблер - всё вполне прокатит, я когда-то пробовал. Но сейчас мне ассемблер юзать нельзя.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 03:00 27-01-2007
    Qraizer



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    И правильно делает, что не пропускает. Посмотри на результаты
    Код:
    #include <iostream>
     
    struct Someclass
    {
      /* ...    */
      virtual void *somemethod(){return this;};
    };
     
    int main()
    {
     std::cout << &Someclass::somemethod << std::endl;
    }
    Это похоже на указатель? Даже если метод невиртуальный, если оптимизатор всунет this в регистр, то твой ассемблерный trick умрёт.
    Что касается исключений, то их нужно перехватывать там, где ты их будешь обрабатывать. Если всё равно, где именно обрабатывать, тогда желательно всё разместить в одном месте, иначе толку от исключений - и так всё можно было бы простыми if()ами прямо по месту обработать.

    Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 18:28 27-01-2007 | Исправлено: Qraizer, 18:31 27-01-2007
    distance

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    А вот такой ещё вопросик тогда При программировании WinAPI/COM/OLE сталкивался. В функции последовательно инициализируются какие-то OLE-объекты (причем, это не С++, а С. т.е., классов нет, возвращаются указатели на структуры), для этого нужно вызвать около 10 функций, и если какая-то из них что-то инициализировать не смогла, то все инициализированные перед этим указатели нужно освободить и вернуть из функции код ошибки

     
    Примерно так:
     

    Код:
     
    void* p1 = NULL;
    void* p2 = NULL;
    void* p3 = NULL;
     
    do
    {
        if ((p1 = malloc(1)) == NULL)
            break;
        if ((p2 = malloc(1)) == NULL)
            break;
        if ((p3 = malloc(1)) == NULL)
            break;
     
        // using p1, p2, p3
     
    } while (FALSE);
     
    free(p1);
    free(p2);
    free(p3);
     

    Всего записей: 878 | Зарегистр. 28-03-2004 | Отправлено: 21:42 27-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    distance
    Да. интересно. И goto не надо. Но опять же в конце нужно проверять:
    if (p1) free(p1);  
    if (p2) free(p2);  
    if (p3) free(p3);  
     
    А вот как бы замутить так, чтобы совсем без лишних действий?

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 21:59 27-01-2007
    distance

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude
    Согласно стандарту, передача NULL в функцию освобождения памяти (free) безопасна.

    Цитата:
    А вот как бы замутить так, чтобы совсем без лишних действий?

    it depends
    std::auto_ptr, boost::shared_ptr, boost::intrusive_ptr, CComPtr и прочее

    Всего записей: 878 | Зарегистр. 28-03-2004 | Отправлено: 22:59 27-01-2007
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru