|
|
  |
Как писать на С++ при создание приложений под ARM, Примеры |
|
|
|
Jun 22 2011, 11:14
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
История моей жизни. Когда-то очень давно, когда компьютеры были большие, микроконтроллеры были 8080, а персональный компьютер был IBM PC/XT с тактовой частотой аж 4.77 MHz.... Но тем не менее фирма Borland выпустила для персоналки первый компилятор C++ V1.0. Я, имея приличный опыт писания на FORTRAN и немного на ASM (хотя наверное приличный, потому-что BOIS для XT у которой сдохла оная пззушка я таки написал), решил воспользоваться плюсами дабы написать программатор РФ-ок. Естественно с окошками, редакторами и прочим. Окошки, конечно, не GUI, а текстовые. Рядом был программист имеющий достаточно большой для тех времен опыт писания на C, и очень отговаривавший меня от C++ - типа громоздко, криво, тормозаааа..... Но я был упорным  . Сидел, грыз книгу, думал, проникался.... Кончилось все спором, кто напишет оконную библиотеку более быструю ( тогда на XT скорость прорисовки можно было вообще наблюдать невооруженным глазом  ) компактнную и за ограниченное время. Спор при все своей опытности коллега проиграл - уж больно все окошки на плюсы хорошо легли  . Потом правда отыгрался - полез в наглую ASM встави делать, подчищать... Я правда в тоже туда-же. В общем библиотечка удалась и использовал я ее долго....Как и C++. Потом пришло осознание того, что Борлондячий компилятор дерьмо редкое, пришлось переходить на другие, пришлось использовать С, поскольку времена были стародавние и плюсовых компиляторов было немного  . Как-то получалось так, что я начал писать в даже на С++ в посконном С стиле, дабы портировать можно было-бы без больших переделок. В общем, я сейчас на плюсах пишу редко, но я не представляю себе, как-бы я писал на C не пройдя школу С++. Там есть масса вещей и подходов которые НЕОБХОДИМО осознать, понять и использовать вне зависимости от языка. Еще скажу, что компиляторы (особо С++) в те времена были реально неумные и ручками на С их при ДОСТАТОЧНОМ ОПЫТЕ можно было таки уделать. Все не стояло на месте - на С++ компиляторы теперь грех жаловаться. Коллеги! Учите и проникайтесь идеями С++, даже если потом будете на BASIC писать.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 22 2011, 11:22
|
Местный
  
Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248

|
Цитата(andrewlekar @ Jun 22 2011, 12:00)  Что-то я не слыхал, чтобы в С++ где-то резко сократились ошибки памяти. Наоборот, прибавилось ошибок. Утечки памяти - фирменная фича неуправляемого С++. В бусте напихали целую кучу умных указателей для борьбы с утечками и всё равно регулярно где-то подтекает на больших проектах. Вы реально пишите глупости... Очевидно что для Вас вопрос выбора между С и С++ это вопрос религии и только Поэтому я бы Вам советовал быть более объктивным уж если Вы пытаетесь давать определенные оценки А если у Вас был неудачный опыт с С++, ну тогда думаю сами знаете что "хорошему" танцору мешает А "ошибки памяти", "Утечки памяти" и прочее прочее это "фирменная фича" неаккуратных и безграмотных "специалистов" а не "неуправляемого С++"
|
|
|
|
|
Jun 22 2011, 11:30
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (andrewlekar @ Jun 22 2011, 18:00)  Потому что разработчики компиляторов умные, а программист только-только Hello World освоил.  if(разработчики_компилятор != программисты) { мир_в_хаосе_и_я_ничего_не_понимаю_в_нем(); panic_kernel(&мой_мозг); } Дайте маленькому ребётенку острый нож, и получите тот же эффект: ребенок будет считать нож злом и говорить всем, что ножом нельзя пользоваться QUOTE (andrewlekar @ Jun 22 2011, 18:00)  Вообще во всём мире С++ верно помирает, а вы наоборот в контроллеры его суете. Да? А мужики-то не знают  Может будем в МК вставлять .NET и Java сразу? QUOTE (andrewlekar @ Jun 22 2011, 18:00)  На С++ я успел поработать и мне не понравилось. И шаблоны, и ОО, и перегрузки - основные фичи С++ - разводят страшную грязь в коде. Да, при хорошем опыте программист научается ходить по этим граблям, но новый программист в проекте будет разбираться очень долго.  Это все субъективно. Есть люди и с противоположным мнением. Кстати, не каждый новый программист код на чистом Си разберет. Я бы скромно предложил закрыть тему, как воинствующую))) QUOTE (zltigo @ Jun 22 2011, 20:14)  хотя наверное приличный, потому-что BOIS для XT у которой сдохла оная пззушка я таки написал Мое Вам уважение! Я дальше самописного бутлоадера (на нулевой дорожки дискеты) и попытки написать примитивную миниОС в защищенном режиме IA32 не ушел. Но это было в далеком 2004 году, сейчас я немного взрослее стал))) Хотя, надо признаться, опыт был неплохой получен. Также делал окна в текстовом режиме, кнопочки и т.д. и т.п. Все на ассемблере...
--------------------
Выбор.
|
|
|
|
|
Jun 22 2011, 11:45
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Danis @ Jun 22 2011, 15:31)  Кстати, прорабатывается новая версия стандарта С++ - это С++ 0x, главной задачей которого является развитие языка С++. Вот тут впринципе не плохо описано, можно пичитать: тыцНу, наконец-то! Цитата В стандартном C++ для перебора элементов коллекции требуется масса кода. В некоторых языках, например, в C#, есть средства, предоставляющие «foreach»-инструкцию, которая автоматически перебирает элементы коллекции от начала до конца. C++0x вводит подобное средство. Инструкция for позволит проще осуществлять перебор коллекции элементов: Код int my_array[5] = {1, 2, 3, 4, 5}; for(int &x : my_array) { x *= 2; } Эта форма for, называемая в английском языке «range-based for», посетит каждый элемент коллекции. Это будет применимо к C-массивам, спискам инициализаторов и любым другим типам, для которых определены функции begin() и end(), возвращающие итераторы. Все контейнеры стандартной библиотеки, имеющие пару begin/end, будут работать с for-инструкцией по коллекции.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 21 2011, 22:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Пописал немного кода на С++ использованием динамического полиморфизма и шаблонов... компиллер юзал gcc-4.6.1. всякую динамическую дрянь, rtti ессно поотключал. Про конструкторы и деструкторы правда пришлось забыть, тк память под обьект обычно выделяется статически(читай, во время ресета контроллера), а инициализировать его можно аж после загрузки какой-то части ОС, при чем для разных классов это может быть по разному (на пример гуи должен стартовать после драйверов итп). Хотя завести init() вместо конструктора для каждого класса и вызвать в нужном месте для нужного обьекта не составляет особого труда. Ради интереса взял кусок своей старой чисто-сишной гуи-либы под 128х64 монохромный дисплей и переписал на С++. В сишной версии рулили всем указатели на таблицы функций(таких как draw,keypressed,...) После переноса этого на плюсы, все было заменено на классы с виртуальными ф-ями и рулить стали указатели на обьекты. Хохма - асм-код остался Идентичен по размеру и инструкциям, только адреса поменялись! А исходник на плюсах стал меньше и гораздо красивее. Оказывается, я уже давно юзаю оо, но все руцями  Далее перевел на плюсы с использованием шаблонов thread-safe queue, сишная версия которого пестрела макросами для реализации поддержки разных типов данных(время на написание этих макросов ушо больше, чем бы я писал отдельные функции для каждого типа  ) Тут сгенерированный код остался Полностью Идентичен сишной версии  В итоге исходный код гораздо проще для понимания, и главное - его просто меньше. Синтаксис обычный сишный. Потери производительности - нулевые. Еще От множественного наследования отказался сразу. Имхо,для 256кб флеша оно не надо, да и во многих оо-языках его нету Обработку исключений не пробовал. по идее, если ее правильно реализовать в компиляторе - производительность должна повысится, в свравнении с техникой возврата кода ошибки, неговоря уже о красоте кода( куча дефайнов с кодами ошибок, куча if,goto, путаница где вызвать printf, где нет итп). Хотя оно не избавляет от проблем выделения/освобождения ресурсов: выделили 10 ресурсов, 11й не вышло - надо освобождать все обратно, а обработчик знать не может что там выделено и сколько, особенно,если там куча вложенных функций, которые тоже что-то выделяли. в итоге городить if/goto всеравно прийдется... Перегрузка операторов и потоков пока вроде не нужна. не нашел места применения. думалось заюзать перегрузку +-=/*% для работы с большими числами(скажем в 2048бит, нужно для таких алгоритмов, как RSA,DSA,...), но очередность там не однозначная получается,многое зависит от компилятора(особенно он любит пихат оператор = там,где не надо), в итоге пожирается память, вызывается довольно тяжелые функции лишний раз, а красота кода не сильно улучшается. на пример а=(b*c)%m у меня: mul(t,b,c); mod(a,t,m); а иногда, если размер a больше чем размер b+c mul(a,b,c); mod(a,a,m); у gcc mul(t,b,c); mod(t1,t,m); equ(a,t1,m); а иногда еще хуже, когда несколько вложенных скобок... по поводу C++11, имхо для embedded ничего полезного. кроме как инициализация отдельных полей структур по имени(уже давно есть в C, в C++ никак не перекочует). Еще в c++ нету VLA (variable length array) - создние в стеке массива неконстантной длины.в c99 это есть и прекрасно работает(при аккуратном использовании) - экономит память.
|
|
|
|
|
Sep 22 2011, 04:49
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(dxp @ Jun 20 2011, 11:32)  - Почему вы ставите знак равенства между С++ и ООП?
Потому что С++ - это язык ООП. Всё остальное, что в нем есть - это (ненужные) навороты, главная его особенность - объектная ориентированность. Цитата(andrewlekar @ Jun 22 2011, 13:00)  Что-то я не слыхал, чтобы в С++ где-то резко сократились ошибки памяти. Наоборот, прибавилось ошибок. Утечки памяти - фирменная фича неуправляемого С++. О как! Сильно сказано. Только вот как раз ООП и придумано для того, чтобы можно было не сократить, а полностью ликвидировать утечки памяти - просто нужно тщательно продумать структуру программы и распределение объектов. И выделять память в конструкторе объекта, а удалять в деструкторе. Тогда их не будте никогда. Разве что у тех программистов, которые так и не поняли смысл объектно-ориентированного программирования. Цитата(andrewlekar @ Jun 22 2011, 11:38)  С++ позволяет множественное наследование, вот и упомянул. Просто перечисление объективных недостатков языка. То есть если в некоем языке есть фича которую вы не понимаете или с которой у вас когда-то были проблемы - то это плохой язык. Вот тот у которого нет такой фичи - хороший. Цитата(andrewlekar @ Jun 22 2011, 11:38)  Адресная арифметика - это также и чисто микроконтроллерная область. И хоть вы на чём пишите, залезать в неё придётся. Зачем? Вот убей не пойму, почему когда пишут прикладную программу для обычного компьютера, она не требуется, а в микроконтроллерах непременно нужна? Цитата(andrewlekar @ Jun 22 2011, 11:38)  А неаккуратная работа с памятью более вероятна как раз в С++, потому что там куда чаще встречается динамическое размещение объектов. Динамическое размещение объектов встречается везде, но в C нет средств для аккуратной работы с ними, а в C++ есть. Цитата(andrewlekar @ Jun 22 2011, 11:38)  На С++ голову уж слишком сильно нужно включать. Да, это серьезный недостаток! На С можно писать и без головы, только... не хотелось бы мне пользоваться таким устройством.
Сообщение отредактировал 777777 - Sep 22 2011, 04:49
|
|
|
|
|
Sep 22 2011, 07:25
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(brag @ Sep 22 2011, 05:05)  Про конструкторы и деструкторы правда пришлось забыть, тк память под обьект обычно выделяется статически(читай, во время ресета контроллера), а инициализировать его можно аж после загрузки какой-то части ОС, при чем для разных классов это может быть по разному (на пример гуи должен стартовать после драйверов итп). Хотя завести init() вместо конструктора для каждого класса и вызвать в нужном месте для нужного обьекта не составляет особого труда. Чем же так конструкторы не угодили? Это просто удобно и безопасно - автоматическая инициализация при создании объектов. А с отдельным init'ом обычное дело забыть сунуть туда инициализатор (люди постоянно ошибаются  ). Цитата(brag @ Sep 22 2011, 05:05)  От множественного наследования отказался сразу. Имхо,для 256кб флеша оно не надо, Необходимость в множественном наследовании зависит не от объёмов программы, а от её концепции и задач. Например, когда надо объединить функционал двух объектов, удобно отнаследоваться от них обоих. Кода это не добавляет. Цитата(brag @ Sep 22 2011, 05:05)  Обработку исключений не пробовал. по идее, если ее правильно реализовать в компиляторе - производительность должна повысится, в свравнении с техникой возврата кода ошибки, неговоря уже о красоте кода( куча дефайнов с кодами ошибок, куча if,goto, путаница где вызвать printf, где нет итп). Не, обработка исключений точно не катит в embedded - это самый тяжёлый механизм С++. Там при выбросе исключения происходит так называемая "раскрутка стека", это длительный процесс со слабопредсказуемыми времянками и значительным потреблением ресурсов - процессорного времени. Цитата(brag @ Sep 22 2011, 05:05)  по поводу C++11, имхо для embedded ничего полезного. Полезная фишка там есть - rvalue reference (обозначается оператором &&). Позволяет избежать ненужного копирования в ряде случаев. Цитата(777777 @ Sep 22 2011, 11:49)  Потому что С++ - это язык ООП. Всё остальное, что в нем есть - это (ненужные) навороты, главная его особенность - объектная ориентированность. Правда? Т.е. сами по себе классы нафиг не нужны? И перегрузка имён функций/операторов не нужна? И возможность объявлять объекты в любом месте программы не нужна? И наследование (без виртуальных функций) не нужно? И шаблоны не нужны? Да будет вам известно, что исходно С++ появился именно как объектный язык, и ОО составляющая была в него добавлена значительно (годы) позже. С++ никогда не был чистым ОО языком - ООП в нём - это лишь один (и не очень обширный) из его аспектов. Либо (если не согласны в вышеперечисленным) вы не вполне понимаете, что такое ООП.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 22 2011, 12:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Чем же так конструкторы не угодили? Это просто удобно и безопасно - автоматическая инициализация при создании объектов. А с отдельным init'ом обычное дело забыть сунуть туда инициализатор (люди постоянно ошибаются ). Да, это удобно и на PC я их использую во всю. а вот конкретно на моей платформе с ними проблеммы... Кога обьект размещен в статической памяти(у меня это только bss забиваемый при старте нулями), gcc создает: 1. константную таблицу init_array с указателями на функции(те самые конструкторы/инициализаторы указателей на vtables). Ессно, если в классе есть виртуальные функции, то GCC по любом создаст конструктор либо дополнит существующий кодом инициализации указателя на vtable 2. саму констнтую vtable пример Код class A{ public: virtual int a()=0; };
class B :public A{ public: B(){z=0x12345;}; int a(){return z++;}; private: int z; };
B bcc; Код Disassembly of section .text: 00008004 <_GLOBAL__sub_I_bcc>: 8004: f240 034c movw r3, #76; 0x4c 8008: f242 3245 movw r2, #9029; 0x2345 800c: 4903 ldr r1, [pc, #12]; (801c <_GLOBAL__sub_I_bcc+0x18>) 800e: f2c0 0301 movt r3, #1 8012: f2c0 0201 movt r2, #1 8016: e883 0006 stmia.w r3, {r1, r2} 801a: 4770 bx lr 801c: 00008038 andeq r8, r0, r8, lsr r0 00008020 <_ZN1B1aEv>: 8020: 6843 ldr r3, [r0, #4] 8022: 1c5a adds r2, r3, #1 8024: 6042 str r2, [r0, #4] 8026: 4618 mov r0, r3 8028: 4770 bx lr 802a: bf00 nop Disassembly of section .rodata: 00008030 <_ZTV1B>: 8038: 00008021 andeq r8, r0, r1, lsr #32 Disassembly of section .init_array: 00010048 <__data_start-0x4>: 10048: 00008005 andeq r8, r0, r5 В итоге, функции по указателям в .init_array должны буть когда-то вызваны до использования обьекта. НО. Некоторые обьекты нужно проинициализировать сразу после ресета(до старта ОС). Некоторые после старта ОС но до старта конкретных драйверов периферии. почему - потому что в их конструкторах есть вызовы функций ОС, если их вызвать до старта ОС - будет креш. А некоторые после старта всех драйверов и до выполнения первого юзерского треда(приложения). Аналогично - там могут быть обращения к дровам, выделение системных ресурсов(создание тредов, мютексов итд). В итоге как мне знать когда вызвать ту или иную функцию(конструктор) из init_array ? Потому я пошел по простому пути - отказался от конструкторов; обрабатываю init_array(туда компиллер кидает код инициализации указателей на vtable) еще до старта системы, что есть безопасно, тк в конструкторах нету системозависимого кода; А уже инициализацию обьектов провожу явно в нужном месте в нужное время посредством вызова init(); Думаю понятно изложил  Цитата Необходимость в множественном наследовании зависит не от объёмов программы, а от её концепции и задач. Например, когда надо объединить функционал двух объектов, удобно отнаследоваться от них обоих. Кода это не добавляет. Ну мож иногда и надо, я пока применению ему не нашел. а про 256кб упомянул с намеком на относительную простоту програм с данным обьемом  Цитата Не, обработка исключений точно не катит в embedded - это самый тяжёлый механизм С++. Там при выбросе исключения происходит так называемая "раскрутка стека", это длительный процесс со слабопредсказуемыми времянками и значительным потреблением ресурсов - процессорного времени. При выбросе исключения явно(путем возврата кода ошибки) тоже происходит раскрутка стека - мы же вернемся в самую первую функцию по цепочке из кодов ошибок: типа ошибка вылезла в недрах uartRead, выходим uartRead->SysCall->GsmModemMuxRead->GsmModemCommand->GprsWrapper->TermRead->main... Хотя с вами соглашусь, "обработка исключений точно не катит в embedded" Цитата Полезная фишка там есть - rvalue reference (обозначается оператором &&). Позволяет избежать ненужного копирования в ряде случаев. Я привык руцями управлять перегонкой данных, ссылки использую в очень редких случаях, в основном только указатели. при паре сотен байт стека, имхо, это дело надо контролировать самому... Цитата При embedded программировании надо, для начала, понять, как устроен конкретный компилятор и его startup файл Привязыватся к компилятору - плохая идея. Мой код дожен компилится любым нормальным компилятором и работать. Компилятор для меня - это именно КОМПИЛЯТОР, тобышь генератор кода, а не набор библиотек и прочей несовместимой хрени. startup у меня свой равно как и ОС. Там и MPU задействован, и куча всяких вкусностей типа lock-free фишек итп, все это не совместимо ни с стандартной библиотекой ни с стартапами(которые тоже являются частью стдлиб), но зато очень удобно в ислопользовании. Цитата где и в каком порядке что должно инициализироваться как я уже писал - компилятор никак не может знать что за чем должно инициализироватся, в сучаи одновременного создания обьектов,тобышь в статической памяыти, ни я не могу быть 100% уверен,что компиллер вдруг запустит конструктор не там, где нужно. Если обьект создается в стеке - тогда да, там можно запросто юзать конструкторы/деструкторы,да и выделение глобальных системных ресурсов для обьекта в стеке конкретного треда/прерывания не целесобразно.
|
|
|
|
|
Sep 22 2011, 12:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Насколько я понимаю, вот тут конструктор object будет вызван в момент первого вызова GetObject(), а не ещё до main() в порядке, определяемом линковкой файлов. Зависит от компилятора... счас проверим на GCC Цитата Только радости от этого по сравнению с object.init() мало -- добавляется кусочек кода в каждом использовании, функции object при вызове GetObject().send() не проинлайнятся, ... по моему init() гораздо красивее этой конструкции...возможности языка нужно применять не ради самих возможностей, а для дела(пользы). благо, Страуструп заложил в язык 2 важные вещи: 1. Он должен быть пригоден для системного программирования (те в окружении неизвестному компилятору,не зависящему одно от другого) 2. Мы не должны платить за то, чего не используем. не конструктора - не паримся с его поддержкой, нет new/delete - не паримся с поддержкой динамики итд...
|
|
|
|
|
Sep 22 2011, 13:03
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(brag @ Sep 22 2011, 19:11)  НО. Некоторые обьекты нужно проинициализировать сразу после ресета(до старта ОС). Некоторые после старта ОС но до старта конкретных драйверов периферии. почему - потому что в их конструкторах есть вызовы функций ОС, если их вызвать до старта ОС - будет креш. А некоторые после старта всех драйверов и до выполнения первого юзерского треда(приложения). Аналогично - там могут быть обращения к дровам, выделение системных ресурсов(создание тредов, мютексов итд). В итоге как мне знать когда вызвать ту или иную функцию(конструктор) из init_array ? Ну, объекты, которые "завязаны" на аппаратуру, организовывать соответствующим образом, но все подряд-то ни к чему под одну гребёнку гладить. Большинство объектов в программе, как правило, не привязаны к аппаратуре, для них можно спокойно использовать конструкторы без ограничений. Цитата(brag @ Sep 22 2011, 19:11)  Ну мож иногда и надо, я пока применению ему не нашел. а про 256кб упомянул с намеком на относительную простоту програм с данным обьемом  256 кБ - весьма приличный объём, если писать код своими руками (а не забить его библиотечными функциями). А по меркам embedded так даже и нифига себе.  Цитата(brag @ Sep 22 2011, 19:11)  При выбросе исключения явно(путем возврата кода ошибки) тоже происходит раскрутка стека - мы же вернемся в самую первую функцию по цепочке из кодов ошибок: типа ошибка вылезла в недрах uartRead, выходим uartRead->SysCall->GsmModemMuxRead->GsmModemCommand->GprsWrapper->TermRead->main... Ну, некоторое сходство есть, но при исключениях там генерируется гора служебного кода, что тащит неслабый оверхед, при организации программы через возврат кода ошибки всё получается на пару порядков скромнее (хотя и не так удобно и красиво внешне). Цитата(brag @ Sep 22 2011, 19:11)  Я привык руцями управлять перегонкой данных, ссылки использую в очень редких случаях, в основном только указатели. при паре сотен байт стека, имхо, это дело надо контролировать самому... Rvalue reference - это совсем не те ссылки, которые в нынешнем С++. Это совсем другая штука.  Обычные ссылки, кстати, тоже, имхо, зря обделяете вниманием - они в ряде случаев дают более простую семантику и более безопасный код. Цитата(brag @ Sep 22 2011, 19:47)  по моему init() гораздо красивее этой конструкции... init() обладает одним существенным недостатком - нужно не забывать корректировать его при изменениях в совсем других частях программы. В общем, это в значительной степени отказ от идеи абстракции (и инкапсуляции) данных в виде законченных объектов, т.е. в некотором роде даунгрейд в С. По мере роста сложности программ, это не добавляет радости.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 22 2011, 13:13
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Object& GetObject() { static Object object; return object; } Хе, еще хуже. Компиллер создает в bss переменную-флаг был ли создан обьект или нет. Далее он проверяет этот флаг. если он не установлен - вызывает функцию __cxa_guard_acquire, которая должна заблокировать этот обьект(типа открыть мютекс) и далее запускает конструктор. потом вызывает __cxa_guard_release и возвращает указатель/ссылку на обьект.  Ессно тело этих функций лежит на нас. И ессно это гемор, проще вызвать init(...) в нужном месте і все
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|