По умолчанию (т.е. если вы не определили копирующий конструктор и копирующее присваивание) компилятор сам генерирует копирующие операции. По умолчанию копирование производится почленно (см. также разделы 14.2.4 и 18.2).
A.12.4. Производные классы
Класс можно определить производным от других классов. В этом случае он наследует члены классов, от которых происходит (своих базовых классов).
struct B {
int mb;
void fb { };
};
class D:B {
int md;
void fd;
};
В данном случае класс
B
имеет два члена:
mb
и
fb
, а класс
D
— четыре члена:
mb
,
fb
,
md
и
fd
.
Как и члены класса, базовые классы могут быть открытыми и закрытыми (
public
или
private
).
Class DD:public B1,private B2 {
// ...
};
В таком случае открытые члены класса
B1
становятся открытыми членами класса
DD
, а открытые члены класса
B2
— закрытыми членами класса
DD
. Производный класс не имеет особых привилегий доступа к членам базового класса, поэтому члены класса
DD
не имеют доступа к закрытым членам классов
B1
и
B2
.
Если класс имеет несколько непосредственных базовых классов (как, например, класс
DD
), то говорят, что он использует множественное наследование (multiple inheritance).
Указатель на производный класс
D
можно неявно преобразовать в указатель на его базовый класс
B
при условии, что класс
B
является доступным и однозначным по отношению к классу
D
. Рассмотрим пример.
struct B { };
struct B1: B { }; // B —
открытый базовый класс по отношению
// к классу B1
struct B2: B { }; // B — открытый базовый класс по отношению
// к классу B1
struct C { };
struct DD : B1, B2, private C { };
DD* p = new DD;
B1* pb1 = p; // OK
B* pb = p; // ошибка: неоднозначность: B1::B или B2::B
C* pc = p; // ошибка: DD::C — закрытый класс
Аналогично, ссылку на производный класс можно неявно преобразовать в ссылку на однозначный и доступный базовый класс.
Более подробную информацию о производных классах можно найти в разделе 14.3. Описание защищенного наследования (
protected
) изложено во многих учебниках повышенной сложности и в справочниках.
A.12.4.1. Виртуальные функции
Виртуальная функция (virtual function) — это функция-член, определяющая интерфейс вызова функций, имеющих одинаковые имена и одинаковые типы аргументов в производных классах. При вызове виртуальной функции она должна быть определена хотя бы в одном из производных классов. В этом случае говорят, что производный класс замещает (override) виртуальную функцию-член базового класса.
class Shape {
public:
virtual void draw; // "virtual" означает "может быть
// замещена"
virtual ~Shape { } // виртуальный деструктор
// ...
};
class Circle:public Shape {
public:
void draw; // замещает функцию Shape::draw
~Circle; // замещает функцию Shape::~Shape
// ...
};
По существу, виртуальные функции базового класса (в данном случае класса
Shape
) определяют интерфейс вызова функций производного класса (в данном случае класса