B C
D
Отметим, что виртуальность класса – это не свойство класса, а результат особенностей процедуры наследования.
Один и тот же класс при множественном наследовании может, включен в производный класс при непрямом наследовании и как виртуальный и как не виртуальный.
X X X
B Y Z C
A
class X {...};
class Y: virtual public X {... };
class Z: virtual public X {... };
class B: public X {... };
class C: public X {... };
class A: public B, public Y, public Z, public C {... };
Объект класса А включает три экземпляра класса X: один виртуальный, общий для классов Y и Z, и два не виртуальных, относящихся к классам В и С.
Виртуальный класс может быть прямым родителем:
class X {... };
class A: virtual public X {... };
class B: virtual public X {... };
class D: public A, public B, virtual public X {... };
X
A B
D
При наследовании, особенно множественном могут возникать неоднозначности при доступе к одноименным компонентам разных базовых классов.
Способ устранения неоднозначностей – использование квалифицированных имен компонент (включающих имена классов и операцию принадлежности “::”).
Каждый раз при создании объекта класса строится указатель, называемый this, и содержащий адрес этого объекта. Правильнее сказать, указатель определяется не в момент создания объекта, а в момент вызова любого из методов объекта.
В связи с неявным определением this является константным указателем, т.е. по умолчанию происходит определение:
имя класса *const this = адрес обрабатываемого объекта
При работе с компонентами класса можно использовать указатель this
Эквивалентно:
Class point { int x, y; Class point { int x, y;
public: public:
point(int xx=0, int yy=0) point(int xx=0, int yy=0)
{this-> x=xx; this ->y =yy;}; { x=xx; y =yy;};
void print (void) void print (void)
{ cout<< this->x <<” “ << this->y;}; {cout<< x <<” “ <<y;};
}; };
В таком использовании нет никаких преимуществ.
Иногда используется при конфликте имен, когда имена формальных параметров функций совпадают с именами компонентов класса:
Class point { int x, y; Class point { int x, y;
public: public:
point(int x=0, int y=0) point(int x=0, int y=0)
{this-> x=x; this ->y =y;}; { point::x=x; point::y =y;};
// используя this // используя квалифицированное имя
…
Часто в функциях - членах класса параметры функции имеют объект некоторого класса (или указатель на объект), а объект еще не существует. Для этого также используется указатель this, обозначающий указатель на тот объект, для которого вызывается данная функция.