Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

21.8. Використання ключового слова asm

Незважаючи на те, що мова програмування C++ – всеосяжна і могутній засіб для створення сучасних програмних продуктів, проте трапляються ситуації, оброблення яких для неї виявляється дуже скрутним1. Щоб справитися з подібними спеціальними ситуаціями, мова C++ надає засіб, який дає змогу увійти до коду програми, написаного мовою Асемблер, абсолютно ігноруючи С++-компілятор. Цим засобом і є настанова asm, використовуючи яку можна вбудувати Асемблерний код програми безпосередньо у С++-програму. Цей програмний код скомпілюється без будь-яких змін і стане частиною коду Вашої програми, починаючи з місця знаходження настанови asm.

За допомогою ключового слова asm у С++-програму вбудовується програмний код, написаний мовою Асемблер.

Загальний формат використання ключового слова asm має такий вигляд:

asm ("код");

У цьому записі елемент код означає настанову, написану мовою Асемблер, яка буде вбудована у С++-програму. При цьому деякі компілятори також дають змогу використовувати і інші формати запису настанови asm:

asm настанова;

asm настанова newline

asm {

послідовність настанов

}

У цьому записі елемент настанова означає будь-яку допустиму настанову мови Асемблер. Оскільки використання настанови asm залежить від конкретної реалізації середовища програмування, то за подробицями реалізації потрібно звернутися до документації, що додається до Вашого компілятора.

На момент написання цього навчального посібника у середовищі Visual C++ (Microsoft) для вбудовування коду програми, написаного мовою Асемблер, пропонувалося використовувати настанову __asm. У всьому іншому цей формат аналогічний опису настанови asm.

Варто знати! Для використання настанови asm необхідно володіти доскональними знаннями мови Асемблер. Якщо Ви не вважаєте себе фахівцем з цієї мови, то краще поки що уникати використання настанови asm, оскільки необережне її застосування може спричинити важкі наслідки для Вашої системи.

21.9. Специфікатор компонування функцій

У мові програмування C++ можна визначити, як функція зв'язується з Вашою програмою. За замовчуванням функції компонуються як С++-функції. Але, використовуючи специфікацію компонування, можна забезпечити компонування функцій, написаних іншими мовами програмування. Загальний формат специфікатора компонування має такий вигляд:

extern "мова" прототип_функції

У цьому записі елемент мова означає потрібну мову програмування. Всі С++-компілятори підтримують як С-, так і С++-компонування. Деякі компілятори також дають змогу використовувати специфікатори компонування для таких мов, як Fortran, Pascal або Visual Basic1.

Специфікатор компонування дає змогу визначити спосіб компонування функції.

Наведений нижче код програми дає змогу скомпонувати функцію myCfunc() як С-функцію.

Код програми 21.16. Демонстрація механізму застосування специфікатора компонування функцій

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

extern "C" void myCfunc();

int main()

{

myCfunc();

getch(); return 0;

}

// Ця функція буде скомпонована як С-функція.

void myCfunc()

{

cout << "Ця функція скомпонована як С-функція.\n";

}

Необхідно пам'ятати! Ключове слово extern – необхідна складова специфікації компонування. Понад це, специфікація компонування повинна бути глобальною; її не можна використовувати в тілі якої-небудь функції.

Використовуючи наступний формат специфікації компонування, можна задати не одну, а відразу декілька функцій.

extern "мова" {

прототипи_функцій

}

Специфікації компонування використовуються досить рідко, і Вам, можливо, ніколи не доведеться їх застосовувати. Основне їх призначення – дати змогу застосування у С++-про­гра­мах кодів програм, написаних іншими організаціями мовами, відмінними від мови C++.

21.10. Оператори вказання на члени класу ".*" і "->"

У мові програмування C++ передбачено можливість згенерувати покажчик спеціального типу, який "посилається" не на конкретний примірник члена в об'єкті, а на члена класу взагалі. Покажчик такого типу називається покажчиком на члена класу (pointer-to-member). Це – не звичайний С++-покажчик. Цей спеціальний покажчик забезпечує тільки відповідний зсув у об'єкті, який дає змогу виявити потрібного члена класу. Оскільки покажчики на члени – не справжні покажчики, то до них не можна застосовувати оператори "." і "->". Для отримання доступу до члена класу через покажчик на член необхідно використовувати спеціальні оператори ".*" і "->".

Оператори вказання на члени класу дають змогу отримати доступ до члена класу через покажчик на цього члена.

Якщо ідея, яку викладено у попередньому абзаці, Вам видалася трохи "невиразною", то наведений нижче приклад допоможе її з'ясувати. У процесі виконання цієї програми відображається сума чисел від 1 до 7. Тут доступ до членів класу myClass(функції sum_it() і змінної sum) реалізується шляхом використання покажчиків на члени.

Код програми 21.17. Демонстрація механізму використання покажчиків на члени класу (початкова версія)

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

class myClass { // Оголошення класового типу

public:

int sum;

void myClass::sum_it(int x);

};

void myClass::sum_it(int x)

{

int i;

sum = 0;

for(i=x; i; i--) sum += i;

}

int main()

{

int myClass::*dp; // Покажчик на int-члена класу

void (myClass::*fp)(int x); // Покажчик на функцію-члена

myClass C_ob;

dp = myClass::sum; // Отримуємо адресу члена даних

fp = &myClass::sum_it; // Отримуємо адресу функції-члена класу

(C_ob.*fp)(7); // Обчислюємо суму чисел від 1 до 7

cout << "Сума чисел від 1 до 7 дорівнює " << C_ob.*dp;

getch(); return 0;

}

Результат виконання цієї програми є таким:

Сума чисел від 1 до 7 дорівнює 28

У функції main() створюється два члени-покажчики: dp (для вказівки на змінну sum) і fp (для вказівки на функцію sum_it()). Звернемо Вашу увагу на синтаксис кожного оголошення. Для уточнення класу використовують оператор дозволу контексту (оператор дозволу області видимості). Програма також створює об'єкт типу myClass з іменем C_ob.

Потім програма отримує адреси змінної sum і функції sum_it() і присвоює їх покажчикам відповідно dp і fp. Як ми вже зазначали вище, ці адреси насправді| є тільки зсувами в об'єкті типу myClass, згідно з якими можна знайти змінну sum і функцію sum_it(). Потім програма використовує покажчик на функцію fp, щоб викликати функцію sum_it() для об'єкта C_ob. Наявність додаткових круглих дужок пояснюється необхідністю коректного застосування оператора ".*". Нарешті, програма відображає значення суми чисел, отримуючи доступ до змінної sum об'єкта C_ob через покажчик dp.

Під час доступу до члена об'єкта за допомогою об'єкта або посилання на нього необхідно використовувати оператор ".*". Але, якщо для цього використовується покажчик на об'єкт, то потрібно використовувати оператор "->*", як показано у цій версії попередньої програми.

Код програми 21.18. Демонстрація механізму використання покажчиків на члени класу (модифікована версія)

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

class myClass { // Оголошення класового типу

public:

int sum;

void myClass::sum_it(int x);

};

void myClass::sum_it(int x)

{

int i;

sum = 0;

for(i=x; i; i--) sum += i;

}

int main()

{

int myClass::*dp; // Покажчик на int-члена класу

void (myClass::*fp)(int x); // Покажчик на функцію-члена

myClass *c, D_ob; // Член c зараз -- покажчик на об'єкт

c = &D_ob; // Присвоюємо покажчику c адресу об'єкта

dp = &myClass::sum; // Отримуємо адресу члена даних sum

fp = &myClass::sum_it; // Отримуємо адресу функції sum_it()

(c->*fp)(7); // Тепер використовуємо оператор "->*" для

// виклику функції sum_it().

cout << "Сума чисел від 1 до 7 дорівнює " << c->*dp; // ->*

getch(); return 0;

}

У цій версії змінна c оголошується як покажчик на об'єкт типу myClass, а для доступу до члена даних sum і функції-члена sum_it() використовують оператор "->*".

Необхідно пам'ятати! Оператори вказання на члени класу призначені для спеціальних випадків, тому їх не варто використовувати для розв'язання звичайних повсякденних задач програмування.