Функція DBConnection :: create () викликає attach (), тому після завершення роботи з об'єктом необхідно звільнити захоплене підключення явним викликом detach (). Зверніть увагу: клас DBClient також управляє з'єднанням за допомогою RAIL При завершенні програми деструктори двох об'єктів DBClient зменшують лічильник посилань (викликом функції detachQ, успадкованої DBConnection від Countable). Підключення до бази даних закривається (через віртуального деструктора Countable) при падінні лічильника до нуля після знищення об'єкта з1.
Підключення функціональності через успадкування частіше здійснюється із застосуванням шаблонів, щоб користувач міг на стадії компіляції вибрати потрібну різновид. Це дозволяє задіяти різні механізми підрахунку посилань без повторного визначення DBConnection. Ось як це робиться:
Параметризрвані підключення функціональності
#ifndef DBCONNECTION H
# Def1ne DBCONNECTION H
class DBConnection. public Database, public Counter
DBConnection (const DBConnectionS): Заборона копіювання
DBConnectionSt operator = (const DBConnection): protected:
DBConnection (const string dbStr) throw (DatabaseError). Database (dbStr)
static DBConnection * createCconst string dbStr) throw (DatabaseError)
DBConnection * con = new DBConnection (dbStr):
assert (con-> refCount () == 1): return con:
Інші необхідні функції.
#endif DBC0NNECTI0N2 H III: -
Єдина зміна - поява шаблонного префікса у визначенні класу (і перейменування Countable в Counter для ясності). Клас доступу до бази даних теж можна було б оформити у вигляді параметра шаблона (якби у нас було кілька класів доступу, з яких вибирався б потрібний варіант), але на цей раз клас вийшов цілком самостійним. У наступному прикладі вихідна реалізація Countable приймає в якості аргументу шаблону, але з таким же успіхом можна було б використовувати будь-який тип, який реалізує потрібний інтерфейс (attach (), detach () і т. Д.):
Підключення функціональності через шаблон
При спадкуванні в похідний клас включаються копії всіх змінних базового класу. Наступна програма демонструє можливе розміщення декількох базових подоб'ектов в пам'яті:
Розміщення подоб'ектов в пам'яті
при множині спадкування
using namespace std:
class С. public A. public В
int mainO cout c == c endl: Конкретний вид результатів залежить від компілятора. DBConnection DBClient (DBConnection int mainO DBConnection assert (db-> refCount () == 2);> III: - Загальний патерн для декількох класів, що підключаються виглядає так: tempiate class Subject. public Mixinl. Хоча ко.мпілятор б не виявив помилку. Втім, проблема вирішується за допомогою оператора dynamiccast - за подробицями звертайтеся до попередньої теми. А * ар = з: У * bp = с; cout ар == static cast cout bp == static cast C * cp = static cast cout cp == static cast cout bp == cp? boolalpha (bp == cp) endl: / * Результат: sizeof (A) == 4 s1zeof (B) == 4 sizeof (C) == 12 c == 1245052 ap == 1245052 bp == 1245056 cp == 1245052 bp == cp? true 0 Як бачите, подоб'екти В об'єкта з знаходиться на відстані 4 байт від початку всього об'єкта. Можна припустити наступну структуру пам'яті:Схожі статті