Программирование >>  Программирование на языке c++ 

1 ... 55 56 57 [ 58 ] 59 60 61 ... 159


book::operator new(sizeof(programmers guide))

При освобождении памяти компшятор вызовет следующую функцию:

book::operator delete(pointer,sizeof(programmers guide))

В общем случае целесообразно объявлять виртуальный деструктор (даже не содержащий операций, например book::-book() {}) во всех классах, которые предположительно будут использованы как базовые. Это предотвратит в будущем возможные ошибки, которые возникают при удалении производного объекта с помощью оператора delete через указатель на соответствующий базовый класс. В работе [1] предложено следующее правило. Если класс X имеет хотя бы одну виртуальную функцию, то в нем следует объявить виртуальный деструктор.

Таким образом спецификация виртуального деструктора позволяет вызвать нужный деструктор через указатель на базовый класс Б, даже если этот указатель в действительности содержит значение, указывающее на производный класс П (Б<-П). Если класс Б содержит виртуальный деструктор и 15<-П, то деструктор класса П тоже будет виртуальным. Рассмотрим пример:

struct А {...............

virtual ~А(); виртуальный деструктор

......................... };

struct В : public А {...............

~В(); тоже виртуальный деструктор

................... };

struct с : public В {.............

~С(); опять виртуальный деструктор

......................... };

В отличие от деструктора конструктор не может быть виртуальным, поскольку ему необходимо знать обо всех деталях построения объекта (в том числе и то, что он имеет базовый объект). Конструктор не является обычной функцией, например, он не может быть вызван для уже существующего объекта. Соответственно не разрешается объявлять указатель на функцию конструктор.

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



объект. Такой псевдовиртуальный конструктор обычно строится с помощью конструктора без аргументов и конструктора для копирования.

Рассмотрим пример:

class book {

public:

book(void); конструктор без аргументов

virtual book* new book(void) { return new book(); }

Здесь виртуальная функция new book возвращает указатель на новый объект, сконструированный с помощью оператора new. В производном классе можно описать новую версию функции new book (напомним, что эта функция является виртуальной), чтобы вернуть объект этого (производного) класса, например:

class programmers guide : pubirc book {

public:

programmers guide(void); конструктор

без аргументов

book* new book(void)

{ return new programmers guide(); }

Это означает, что для заданного объекта пользователь может создать новый объект того же типа:

void function(book* pb)

{ book* pb new = pb->new book(); }

Теперь, если в функцию function передать указатель на объект класса book, то pb new будет указателем на новый объект класса book. Если же в функцию function передать указатель на объект класса programmers guide, то pb new будет указателем на новый объект класса progranimers guide.

Виртуальный конструктор для копирования можно определить примерно так же:



class book {

public:

void copy(book* new p) { *this = *new p; } virtual book* copy constructor(void);

book* book::copy constructor(void) { book* n b = new book;

n b->copy(this);

return n b; }

Теперь можно использовать этот конструктор для копирования, например, так:

void function(book* pb)

{ book* pb new=pb->copy constructor(); }

Можно так же определить конструктор для копирования с одним аргументом, который будет указывать, что мы хотим в действительности скопировать. Например, мы хотим скопировать только сам объект (как это сделано выше) или целое множество взаимосвязанных объектов, представленных, скажем, в виде бинарного дерева (соответствующий пример дан в работе [1, с. 218-219]).

Рассмотрим примеры. Две первые программы показывают различия, имеющие место при объявлении виртуального деструктора. В первом примере виртуальный деструктор не объявляется.

#include <iostream.h>

struct А {

А() { cout A CON\n ; } конструктор ~А() { cout A DES\n ; } деструктор

struct В : public А {

В() { cout B CON\n ; } конструктор ~В() { cout B DES\n ; } деструктор

struct С: public В {

СО { cout C CON\n ; } конструктор



1 ... 55 56 57 [ 58 ] 59 60 61 ... 159

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.003
При копировании материалов приветствуются ссылки.
Яндекс.Метрика