subj — как? Например, в таком коде:
class Base{
...
};
class Child:public Base{
void f(){cout<<"Base";}
};
...
Base * p = new Child;
p->f();
При этом, вообще говоря, я точно не знаю, что запишется в p — Child или Base (через p = new Base

. Во втором случае, разумеется, f вызывать не надо. Могу ли я вообще выяснить, что в указателе p у меня сидит — Child или Base?
Всем заранее спасибо.
gde11 wrote:
g> subj — как? Например, в таком коде:
g> class Base{
g> ...
g> };
g> class Child:public Base{
g> void f(){cout<<"Base";}
g> };
g> ...
g> Base * p = new Child;
g> p->f();
g> При этом, вообще говоря, я точно не знаю, что запишется в p — Child или Base (через p = new Base
. Во втором случае, разумеется, f вызывать не надо.
Можно сделать функцию f() виртуальной.
struct Base
{
virtual void f() { /* ничего здесь не делаем */ }
};
struct Child : Base
{
virtual void f() { cout << "Child"; }
};
// ...
Base* p1 = new Base;
Base* p2 = new Child;
p1->f(); // вызов Base::f
p2->f(); // вызов Child::f
g> Могу ли я вообще выяснить, что в указателе p у меня сидит — Child или Base?
Можешь при помощи dynamic_cast<> (при преобразовании к указателю вернет 0, если Base не является на самом деле Child):
if(Child* с = dynamic_cast<Child*>(p))
c->f();
Posted via RSDN NNTP Server 1.8 beta
Здравствуйте, gde11, Вы писали:
G>При этом, вообще говоря, я точно не знаю, что запишется в p — Child
G>или Base (через p = new Base
Перегрузка и виртуальные функции.
Я постараюсь, решить сразу две проблемы, вызов базового
класса через производный, а так же присутствие виртуальных
функций в базовом классе.
Итак. Если мы используем virtual определения функций в
базовом и соответственно в наследуемом классе, то это —
полиморфизм. Что это такое, "... способность объекта
изменять форму во время выполнения программы...".
Например:
include "iostream.h"
class CPhone
{
public:
virtual void Call()
{
printf( "\n Я базовый класс Phone");
}
};
class CPayPhone : public CPhone
{
public:
virtual void Call()
{
printf( "\n Опустите монету, класс CPayPhone \n" );
}
};
int main(int argc, char* argv[])
{
CPhone _obj_Phone;
CPayPhone _obj_PayPhone;
// N% 1
_obj_Phone.Call();
_obj_PayPhone.Call();
/* output.
Я базовый класс Phone
Опустите монету, класс CPayPhone
*/
// N% 2
CPhone* pnt_2 = &_obj_Phone;
pnt_2->Call();
/* output.
Я базовый класс Phone
*/
// N% 3
CPhone* pnt_3 = &_obj_PayPhone;
pnt_3->Call();
/* output.
Опустите монету, класс CPayPhone
*/
return 0;
}
Разбор полетов.
Если при организации указателя на класс участвуют оба
класса необходимо посмотреть определены ли в базовом классе
виртуальные функции. Почему ? Потому как, если данное
определение(virtual) присустствует, вызывается функция того
класса который стоит справа(естественно, кастинг должен быть
корреректный, справа стоит производный класс).
Если НЕТ виртуальных функций, что определено слева, то и
вызывается !!!
// cod.
CPayPhone obj;
CPhone* pnt = &obj;
// ссылка на класс CPayPhone, если функция Call() определена,
// как виртуальная.
CPhone* pnt = &obj;
// если виртуальных функций в базовом классе не определено,
// то эта ссылка на класс CPhone, даже если физически написано
// &obj( указатель на CPayPhone).
Уважаемый gde11, по моему скромному мнению, можно
перекопировать и запустить данный пример, посмотрев, при
этом что будет выводиться на экране. Поэкспериментировать,
например, УБРАВ !!! virtual в базовом классе.
Маленький совет(правило правой руки):
class CPhone* = &class CPayPhone;
Если в классе CPhone, определена виртуальная функция. И
после данного равенства вызывается именно она, будет
ипользованна функция класса CPayPhone. Другими словами,
полиморфизм — возможность менять поведение, если это так, то
я хочу поменять поведение моего базового класса, как ?
Присвоив ему указатель на производный, т.е. тот, который,
стоит справа. Поэтому в данном случае вызывается функция
Call класса CPayPhone.
Успехов...
... << RSDN@Home 1.1.0 stable >>
Исправлена подсветка синтаксиса. -- ПК.