Язык программирования C++ для профессионалов


Виртуальные конструкторы - часть 2


void user(expr* p1, expr* p2) { expr* p3 = p1->new_expr(); expr* p4 = p2->new_expr(); // ... }

Переменным p3 и p4 присваиваются указатели неизвестного, но подходящего типа.

Тем же способом можно определить виртуальный конструктор копирования, называемый операцией размножения, но надо подойти более тщательно к специфике операции копирования:

class expr { // ... expr* left; expr* right; public: // ... // копировать `s' в `this' inline void copy(expr* s); // создать копию объекта, на который смотрит this virtual expr* clone(int deep = 0); };

Параметр deep показывает различие между копированием собственно объекта (поверхностное копирование) и копированием всего поддерева, корнем которого служит объект (глубокое копирование). Стандартное значение 0 означает поверхностное копирование.

Функцию clone() можно использовать, например, так:

void fct(expr* root) { expr* c1 = root->clone(1); // глубокое копирование expr* c2 = root->clone(); // поверхностное копирование // ... }

Являясь виртуальной, функция clone() способна размножать объекты любого производного от expr класса.

Настоящее копирование можно определить так:

void expr::copy(expression* s, int deep) { if (deep == 0) { // копируем только члены *this = *s; } else { // пройдемся по указателям: left = s->clone(1); right = s->clone(1); // ... } }

Функция expr::clone() будет вызываться только для объектов типа expr (но не для производных от expr классов), поэтому можно просто разместить в ней и возвратить из нее объект типа expr, являющийся собственной копией:

expr* expr::clone(int deep) { expr* r = new expr(); // строим стандартное выражение r->copy(this,deep); // копируем `*this' в `r' return r; }

Такую функцию clone() можно использовать для производных от expr классов, если в них не появляются члены-данные (а это как раз типичный случай):

class arithmetic : public expr { // ... // новых членов-данных нет => // можно использовать уже определенную функцию clone };

С другой стороны, если добавлены члены-данные, то нужно определять собственную функцию clone():




- Начало -  - Назад -  - Вперед -



Книжный магазин