В С++ допускается присваивать адрес производного класса указателю базового, так как его использование в таком контексте вполне корректно. Указатель на базовый класс используется для доступа к членам, определенным только в базовом классе. Все они также определены внутри производного класса путем наследования. Следовательно, если указатель содержит адрес объекта производного класса, то можно получить значение любого члена класса, на который задана ссылка с помощью указателя. Указатель на базовый класс, используется для того чтобы получить доступ ко всем объектам, созданным от классов наследников. Однако, возможен доступ только к членам, унаследованным от базовых классов.
Пример:
class Point
{
public:
int x,y;
Point ():x(50),y(50) {}
Point (int nx,int ny):x(nx),y(ny) {}
void Show()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
};
class ColorPoint: public Point
{
public:
int color;
ColorPoint():Point(100,100),color(0) {}
ColorPoint(int nx, int ny, int ncolor): Point(nx,ny),color(ncolor) {}
void Show()
{
cout <<x<<","<<y<<endl;
}
};
void main()
{
Point p(10,10);
ColorPoint cp(20,20,1);
p.Show();//(10,10)
cp.Show();//20,20
Point *pp=new ColorPoint(25,25,5);
cout<<pp->x<<endl;//25
cout<<pp->y<<endl;//25
//cout<<pp->color<<endl; //error
//мы не можем обращаться к свойству color, т. к. в базовом классе Point такого свойства //просто нет
pp->Show(); (25,25)
}
Таким образом, мы можем получить доступ к свойствам и методам базовых классов. Однако, здесь отрабатывает функция Show() класса Point. Для того, чтобы отрабатывала функция Show(), нам необходимо использовать виртуальные функции. Добавим перед описанием функции Show() ключевое слово virtual. В классе ColorPoint тоже можно добавить слово virtual, хотя, это и не имеет смысла, т. к. в данном случае, Show() – будет функцией наследуемой.
Этот механизм называется «поздним связываением», т. к. в этом случае, адрес вызываемой функции на этапе компиляции еще не известен. Этот механизм более ресурсоемок, и работает медленнее, однако, обеспечивает более гибкое программирование.
virtual void Show()
При такой организации, запущена будет организация функии, описанная в классе ColorPoint.
pp->Show(); // 25,25 без скобок
Здесь так же стоит отметить, что функция Show () класса ColorPoint уже может обращаться к свойствам, определенным только в классе ColorPoint, если конечно все конструкторы написаны правильно.
void ColorPoint::Show()
{
cout <<x<<","<<y<<”,”<<color<<endl;
}