Розширення мови C + + в CBuilder

Програмісти, що працюють на традиційному C + + різко критикують CBuilder через те, що фірма Borland втілила його компілятор, застосувавши несумісні розширення мови Однак якщо розглянути всі аспекти, то виявиться, що це вельми непереконливий аргумент Зрештою, якщо ви хочете писати код на стандартному C + +, вам ніщо не заважає – CBuilder легко його обробить Не хочете працювати з розширеннями, не треба – воля ваша CBuilder без проблем працює з мовою C + + стандарту ANSI, і на ньому ви можете створювати повноцінні програми під Windows, не використовуючи VCL При бажанні ви можете зробити все, що я тільки що перерахував Тільки навіщо

Головним аргументом проти XE VCL використання VCL зазвичай є проблема XE C + +: проблема сумісності сумісності Дійсно, ви не зможете працювати з кодом поза середовища CBuilder Як не дивно, подібні докори не адресують Visual Basic або Delphi, але фанатики C + + наполягають на сумісності, що насправді досить нерозумно Ви не будете використовувати CBuilder для створення мультиплатформових додатків, ви використовуєте його для створення найкращих додатків під Windows в найкоротший термін

У цьому розділі ми розглянемо ті розширення XE C + +: розширення стандартної мови C + +, які роблять CBuilder унікальним Ми побачимо, коли варто їх застосовувати, а коли ні Є буквально кілька випадків, в яких ви дійсно повинні застосовувати розширення CBuilder, і ми розглянемо їх Треба сказати, що C + + це і так досить складний і разом з тим потужний мову, так що не варто використовувати у своїх додатках більше того, що дійсно необхідно

Давайте розглянемо кожне розширення, що використовується в CBuilder

Ключові слова, що мають XE ключові слова: _asm і __ asm у своєму складі XE __asm, ключове слово корінь asm, можуть XE _asm, ключове слово використовуватися по черзі Кожне з них (включаючи і не вказане в заголовку ключове слово asm) просто-напросто надає вам можливість помістити у вихідний код вашого XE асемблер додатки інструкції мови асемблер не повязуючи з асемблерними модулями Ключове слово asm вже присутня деякий час в різних компіляторах фірми Borland і добре

зарекомендувало себе для використання з вбудованим асемблером Як правило, ви будете використовувати цей тип коду для збільшення швидкості або доступу до системних регістрів і портів Якщо ви до цих пір не вмієте писати на асемблері, можу сказати точно, що CBuilder – не кращий полігон для навчання

Ключове слово automated використовується XE ключові слова: __automated для властивостей XE __automated, ключове слово типу OLE automation в ваших XE OLE automation компонентах Будь-яке властивість, певне як automated, за замовчуванням є публічним (public) у вашому класі Різниця полягає в тому, що автоматизовані властивості вимагають для доступу до себе використовувати функції-члени класу Так що для взаємодії з такими властивостями ви не зможете використовувати просто змінні-члени класу Крім того, для цих функцій класу ви повинні використовувати модифікатор fastcall Для автоматизованих властивостей ви не можете використовувати модифікатори index, stored, default або nodefault

XE ключові слова: _cdecl і __ cdecl Ці XE _cdecl, ключове слово ключові слова XE __cdecl, ключове слово визначають, що функція або метод використовують протокол стилю C це означає, що функція компонується з урахуванням регістра букв і додаванням подчерка (_) в початок імені функції Використання цих варіантів так само впливає на те, як CBuilder передає змінні в стек Останній параметр поміщається в стек першим за очищення стека відповідальність несе блок коду, що викликав цю функцію Для використання функцій або змінних cdecl у своїй програмі вам треба всього лише використовувати модифікатор, і більше нічого Інше зробить за вас компілятор

XE функції: __classid Функція classid використовується XE __classid, функція для того, щоб отримати покажчик на віртуальну таблицю класу в бібліотеці VCL Ця функції використовується всередині самої системи CBuilder для роботи з обєктами і методами VCL, які вимагають для позначення обєкта, з яким працюють, використовувати покажчик this Незважаючи на те, що

__classid представляє з себе велику частину вбудованої в CBuilder внутрішньої системи ідентифікації типів під час виконання, це твердження краще не використовувати в прикладних програмах Фірма Borland залишає за собою право змінити поведінку цієї функції, так що всі програми, налаштовані на яке-небудь конкретне поведінку компілятора, швидше за все не будуть працювати в наступних версіях В якості загального зауваження скажу, що цей вираз лежить в основі взаємодії обєктів C + + в CBuilder і VCL, заснованої на мові Pascal

XE вирази: __closure Вираз __ closure XE __closure, вираз використовується для декларацій функцій обробки подій Closure – це спеціальний вид XE покажчики: загальні моменти покажчика на функцію, що використовується у більшості функцій в бібліотеках Windows На відміну від звичайних покажчиків на функції, ці містять не тільки адресу викликається функції (четирехбайтний покажчик), але так само і покажчик на обєкт, для якого викликається подія (покажчик this) Використання вираження __ closure деяким чином обмежує можливості системи, так як при ньому можливо використовувати лише обмежене число обєктів одного класу На щастя, оскільки це повязано з покажчиком на адресу, число таких обєктів дуже велике В осяжному майбутньому вам немає потреби хвилюватися за кількість обєктів-якого класу у вашому додатку

Використання покажчиків closure – вельми важлива концепція, здійснена в CBuilder, і для того, щоб самостійно писати свої обробники подій в системі, вам доведеться освоїти цю концепцію Базовий формат цих покажчиків такий же, як і у функцій-членів класу в системі:

class MyClass

{

&lt  void ACallbackFunction( int x, double y, char *z )

}

< / / Визначаємо closure

&lt  void (__closure *CallbackEvent)(int, double, char *)

< / / Тепер можна зіставити його об'єкту потрібного класу

&lt  MyClass *obj = new MyClass

&lt  CallbackEvent = obj-&gtACallbackFunction

Насправді при роботі з обработчиками подій ви привласнюєте і змінюєте покажчики на функції-члени класу Незважаючи на те, що робота з функціями класу це дуже невдячне заняття в C + + взагалі, CBuilder використовує кращі сторони цієї ідеї в концепції використання вираження closure

XE модифікатори: __declspec Модифікатор

__declspec XE __declspec, модифікатор в

CBuilder використовується двома незалежними способами По-перше це модифікатор для імпортованих і XE функції: DLL експортованих функцій в XE DLL DLL CBuilder Це вираз використовується замість наявного в більш ранніх компіляторах модифікатора

__export У цього виразу було кілька слабких місць, основне – він повинен був знаходитися завжди у фіксованій позиції в коді додатків Наприклад, не можна було написати:

__export void func(void)

якщо ви хотіли експортувати функцію func Замість цього ви повинні були писати: void __ export func (void)

Це було подразнюючу обмеження У C + + вкрай рідко зустрічаються місця, в яких важливий порядок, в якому ви маєте в своєму розпорядженні опису Єдина річ, у який спостерігається щось хоча б віддалено подібне, це модифікатор const, який може вживатися в різних позиціях, але означає різні речі в залежності від займаної позиції

Модифікатор __ declspec поводиться не так Використовувати його можна таким чином: void __ declspec (dllexport) funct (void)

__declspec(dllexport)void  funct(void)

Обидва ці вирази припустимі і коректні Обидва вони експортують функцію, звану funct в DLL з CBuilder Це вираз часто використовується в прикладних програмах і динамічно підключаються бібліотеках, так що звикайте використовувати його в своєму коді

XE вирази: __except Вираз __ except еквівалентно XE except, вираз висловом

except Воно використовується при обробці виняткових XE обробка виняткових

ситуацій ситуацій в С + + для визначення дії, яке повинно проводитися при виникненні заданої помилки усередині блоку try Основна відмінність між виразами try .. catch і __ try .. except полягає в тому, що try .. catch використовується в додатках на C + +, а __ try

… __ Except використовується в структурованих додатках на C Загальний вигляд вираження except приблизно наступний:

__try

{

< / / Деякі вирази, які можуть спричинити за собою

< / / Виняткову ситуацію

}

__except(someexpression)

{

}

Якщо ви пишіть код для своїх додатків в CBuilder тільки на C + +, вам ніколи не доведеться використовувати вирази __ try або __ except Проте ці вирази можуть використовуватися в коді, успадкованому від С, який включається в проекти CBuilder Використовуючи структуровану обробку виняткових ситуацій, ви працюєте в рамках підтримуваної 32-розрядними версіями Windows системи обробки, при цьому ви домагаєтеся сумісності з механізмом обробки виняткових ситуацій CBuilder, вбудованим в VCL

XE модифікатори: _export і __ export Модифікатор export XE _export, модифікатор: використовується XE __export, модифікатор для експорту класів, функцій і даних усередині DLL CBuilder для використання в інших додатках Є кілька різновидів цього модифікатора, які ви можете використовувати в своїх додатках

class __export MyClass

{

}

Подібний вид вираження означає, що внутрішній клас MyClass повинен бути експортований для використання в інших додатках Підключивши відповідний заголовний файл класу і бібліотеку імпорту вашої DLL розробники додатків можуть використовувати клас MyClass також, як якщо б він був частиною їх власного додатка

void __export Function(void)

{

}

Цей вид вираження експортує окрему функцію C + + (або С) із заданого XE DLL: експорт функцій модуля DLL Зверніть увагу на те, що ви можете експортувати будь-яку (хоч всі) функцію в DLL, при бажанні не надавши користувачу доступу до внутрішніх функцій Повинен відразу ж одне попередження щодо експортування функцій з DLL подібним чином Ви експортуєте функцію по імені, а не порядковому номеру, а використовувати порядковий номер набагато ефективніше, та й завантажується він швидше Так що описаний ваше варіант не підходить для випадку, коли вас хвилює швидкість завантаження функцій з DLL Різниця вимірюється, природно, всього лише мілісекундами, але і це може

бути помітно у високопродуктивних додатках, особливо якщо функція з DLL

викликається багато разів за невеликий проміжок часу int __ export nDataValue

Останній різновид вираження __ export використовується для експорту власне XE DLL: експорт даних значень даних з DLL в додаток Звичайно, навряд чи ви будете часто використовувати подібне у своїх додатках, але іноді вам може знадобитися експортувати прапори помилок або змінні статусу

Коли може виникнути потреба у використанні вираження export В основному в тому випадку, якщо ви не захочете возитися з файлами опису модуля (DEF-файлами) і виразами EXPORT в файлі опису, які визначають ті частини DLL, які ви хочете зробити видимими для інших додатків в системі

XE модифікатори: _fastcall і fastcall Одним XE _fastcall, модифікатор з найбільш XE __fastcall, модифікатор важливих розширень в системі CBuilder є модифікатора

__fastcall, яке робить можливим використовувати засновані (і написання) мовою XE Pascal Pascal обєкти VCL в ваших XE Delphi і CBuilder: синтаксис додатках на C + + Використання модифікатора fastcall дає інструкцію компілятору згенерувати код, який передає параметри у функції через системні регістри, тобто також, як це передбачається в Pascal

Правила XE __fastcall: правила ісполдьзованія використання __ fastcall дуже прості Якщо ви експортуєте зі свого класу метод, який повинен бути використаний в Object Inspector або де-небудь ще, в описі функції ви повинні використовувати модифікатор __ fastcall Якщо ви заміщаєте метод VCL, який визначений з використанням модифікатора fastcall ви так само повинні використовувати цей модифікатор при описі вашого методу Оскільки __ fastcall не успадковується, ви повинні вказувати його на кожному рівні класу, який здійснює заміщення подібного методу

Наприклад, якщо ви заміщаєте метод Paint компонента в класу, успадковує від обєкта VCL, вам треба написати наступне:

virtual void     fastcall Paint(void)

Це необхідно, оскільки Paint насправді написаний на мові Pascal в обєкті VCL З іншого боку, якщо ви хочете втілити у вашому класі нову функцію, яка викликає обєкт VCL низького рівня, не потрібно використовувати модифікатор fastcall для нового методу

Уявіть, наприклад, що вам треба створити новий метод, який би перемикав стан форми видима / невидима (Hide / Show), навіть не знаючи поточного стану Метод, який ми назвемо Toggle, може бути задекларований наступним чином:

virtual void Toggle(void)

У цьому випадку модифікатор fastcall не потрібен, оскільки такої функції немає в VCL Те, що насправді вона втілена з використанням методів VCL, ролі не грає Нижче представлений один з можливих варіантів втілення цієї функції, що показує використання лежать в основі компонента методів VCL:

void  TMyComponent::Toggle(void)

{

&lt  if ( Visible ) Hide()

&lt  else

Show()

}

Важливо не забувати використовувати XE методи: заміщення модифікатор __ fastcall при заміщенні XE заміщення методів: синтаксис методів Якщо ви цього не зробите, то в кращому випадку функція не працюватиме, оскільки варіант, написаний вами, просто не буде викликатися, а в гіршому програма видасть виняткову ситуацію і припинить роботу

XE вирази: __finally Вираз finally використовується XE __finally, вираз разом з виразом try для обробки виняткових ситуацій, використовуючи для цього

структуровані виняткові ситуації Оскільки вираження __ try і

__finally

використовуються тільки у файлах і функціях C, немає потреби хвилюватися з їх приводу в CBuilder,

оскільки ці вирази не будуть використані всередині IDE

Для використання зовнішніх функцій C і структурованої обробки виняткових ситуацій, що надається CBuilder і мовою C + + вам доведеться використовувати версію компілятора в командному рядку

XE вирази: _import і import Метою вираження import в CBuilder XE _import, вираз є визначення XE __import, вираз того, що клас, функція або блок даних повинен бути імпортований із зовнішнього джерела Ви можете імпортувати певні класи із зовнішніх DLL або бібліотек, так само, як і функції на мові C Використовуючи одну з різновидів вираження про імпорт, елементи даних, певні в зовнішніх DLL можуть сприйматися також, як якщо б вони були частиною програми, в якій їх використовують

Вирази _import і import використовуються як модифікатори для типів імпортованих елементів Існує три види цього виразу, кожен – для одного з типів, які можуть бути імпортовані подібним чином:

class _import MyClass

{

}

Це вираз XE імпорт класів: визначає імпортований клас XE класи: імпортування CBuilder згенерує весь код, необхідний для того, щоб завантажити клас з підключеною DLL (природно, тільки якщо він буде там знайдений), так що ви можете просто визначати екземпляри цього класу у вашому додатку

int __import MyFunction(int arg1)

Це вираз визначає функцію, певну десь зовні – в бібліотеці або DLL, яка приймає одне ціле число у вигляді аргументу, а інше повертає Відзначте, що модифікатор

__import пишеться після типу значення, що повертається функції, визначеної зовні додатки

int _import MyData

Ця остання різновид вираження являє певне зовні ціле значення, яке буде дозволено під час складання компілятором і компоновщиком Модифікатор _import для елементів даних завжди розташовується між типом даних і імям змінної У це ж місце можуть бути вставлені та інші модифікатори (наприклад, volatile)

XE вирази: __intX Ці вирази XE __intX, виразу дозволяють визначити розмір цілих чисел для змінних в системі Число, наступне за __ int позначає кількість бітів, яке змінна буде займати в памяті Наприклад, тип змінної int16 визначає змінну, що займає в памяті 16 бітів (стандартне ціле в Windows)

Як приклад уявіть, що вам треба визначити константу, значення якої дорівнює 9 Цілком імовірно, що ви захочете заощадити память і виділити під цю константу тільки 8 бітів Для цього вам слід написати:

__int8 iVal = 9

XE ключові слова: _pascal і __ pascal Ключове XE _pascal, ключове слово слово __ pascal визначає XE __pascal, ключове слово метод передачі даних у функції і методи в системі CBuilder Угоди викликів в стилі XE Delphi і CBuilder: конвенції виклику Pascal мають два помітних відмінності від стандартних викликів в стилі С По-перше, функції XE функції: мови Pascal Pascal НЕ XE Pascal розрізняють регістр букв, так як всі вони насправді зберігаються у вигляді великих літер Це дозволяє компілятору без праці підключати нові модулі в систему У С + + функції стилю Pascal все ще калічаться, але імена функцій перетворюються у верхній регістр

Друга відмінність угод, прийнятих у функціях стилю Pascal, складається в порядку занесення аргументів на стек Незважаючи на те, що вас це не торкнеться до тих пір, поки ви не почнете писати код на асемблері для виклику цих функцій, важливо виділяти ті випадки, коли функція має формат Pascal Неправильне використання цього формату приведе до виняткової ситуації під час виконання Завжди використовуйте модифікатор __ pascal при викликах методів VCL

XE модифікатори: __property Одним з XE __property, модифікатор найбільш важливих нових модифікаторів можна вважати вираз __ property Це XE властивості: синтаксис вираження служить для того, щоб показати компілятору, що він має справу з властивістю обєкта стилю VCL Властивості надають спеціальні функції read і write для доступу до зберігаються в них даними Використання модифікатора __ property показує компілятору, що прямий доступ до властивості можливий не завжди, як це показано в наступному прикладі:

private

int FMyInt public

void __fastcall SetInt(int iNewInt)

__published

__property int MyIntProperty = {read=FMyInt, write=SetInt}

У даному випадку ми показуємо, що користувач має право читати властивість, отримуючи при цьому значення внутрішньої змінної класу FMyInt При спробі запису нового значення властивості компілятор по-тихому викличе метод обєкта, названий SetInt Нижче наведений якийсь код, який допоможе вам краще зрозуміти ці моменти:

TMyObject * pObject = new TMyObject (NULL) / / Створюємо

/ / Екземпляр

pObject-> MyIntProperty = 164 / / Виклик SetInt

int nInt = pObject-> MyIntProperty / / Отримуємо значення

< / / Змінної класу FMyInt

Памятайте, що використання виразу property автоматично спричинить необхідність написання якогось коду для звернення до властивості Незважаючи на великі можливості по доступу до властивостей, сам код буде на занадто великий, так що не варто сильно переживати з цього приводу Вираз __ property зустрічається в додатках і компонентах CBuilder вельми і вельми часто

XE ключові слова: __published Ключове слово

__published використовується XE __published,

ключове слово для того, щоб дати знати компілятору про своє бажання бачити деякі властивості даного обєкта відображеними в Object Inspector Секцію published можуть містити тільки обєкти, наследующие від TObject На відміну від багатьох інших виразів і модифікаторів, вираз published відноситься не до одного рядка, а може розглядатися як вираження визначення прав доступу (як і private, protected або public) і визначати властивості обєкта, які будуть публічними, і при цьому ще й відображатися у вікні Object Inspector Використання цього виразу призведе так само до того, що інформація про обєкт, що містить вираз __ published, буде містити дані часу виконання про XE RTTI ідентифікації типів (Runtime Type Identification, RTTI), представлені в стилі Delphi що може бути використано для формування запитів до обєкта про існуючі в ньому властивості і методах

XE ключові слова: __rtti Також як і __ published, XE rtti, ключове слово вираз __ rtti примушує компілятор створювати ідентифікацію часу виконання для класу або структури До тих пір, поки ви не дозволь йому робити зворотне, компілятор за замовчуванням буде генерувати інформацію XE RTTI RTTI Ви можете використовувати прапор командного рядка – RT-для того, щоб компілятор не створював інформацію RTTI про програму та її даних в цілому Якщо ви так зробите, але при цьому захочете, щоб деякі класи або структури в програмі використовували RTTI, вам слід використовувати модифікатор __rtti, застосовуючи наступний синтаксис:

struct     rtti MyStructure {}

При цьому структура MyStructure буде згенерована з даними часу виконання про ідентифікацію типів, після чого можна запросити цю інформацію, використовуючи у своєму додатку класи typeinfo і typeid

XE модифікатори: __thread Модифікатор __ thread використовується XE __thread, модіфікаторр для оголошення глобальних змінних, унікальних для кожного потоку Наприклад, якщо ви хочете завести окрему глобальну змінну в якості прапора, що показує, завантажений чи ні якийсь даний файл, вам варто використовувати логічну глобальну змінну Однак ця змінна може відрізнятися в різних потоках кожен потік може потребувати завантаженні своєї версії файлу Файл може бути так само і протоколом роботи, при цьому зовсім не обовязково, що всі потоки повинні писати в один і той же протокол У цьому випадку вам буде потрібно прапор цього протоколу, унікальний для кожного потоку, в якому він використовується Для цього вам і треба буде використовувати модифікатор __ thread для змінних

Синтаксис модифікатора thread має наступний вигляд: int __ threadbFileOpen = FALSE

Є кілька обмежень на використання модифікатора thread, найважливішим з яких є те, що цей модифікатор не можна використовувати в рядках, що містять ініціалізацію, можливу тільки під час виконання Це означає, що вирази типу:

int __thread nNumTimes = GetNumberOfTimes()

не працюватимуть, оскільки значення функції може бути обчислено тільки під час виконання Це обмеження поширюється також і на обєкти, оскільки для їх створення потрібно використання конструктора, що також можливо тільки під час виконання Тільки прості типи даних можуть бути використані з модифікатором thread Інша важлива обмеження повязане із забороною на використання цього модифікатора у функціях або покажчиках, оскільки вони є просто адресами памяті, які не можуть бути зіставлені з кожним потоком

Так само як і except, XE __try, вираз вираз try є варіантом обробки виняткових ситуацій, використовуваним тільки в програмах на С При роботі з програмами, що використовують С + + (Такими, як CBuilder), використовуйте замість нього вираз try Для отримання допомоги з використання вираження try дивіться статтю, присвячену висловом except

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*