Возникла непонятка с виртуальными методами классов
В процессе изучения C++ возникла непонятка с виртуальными методами классов. Допустим есть три класса: A, B и C. Классы B и C публично наследуются от класса A. В классе A публичным объявлен виртуальный абстрактный метод Test(). В классах B и С этот метод переопределяется, причем в классе C данный метод объявлен уже как приватный. В функции MAIN создается массив указателей на объекты с типом A, элементам которого присваиваются адреса объектов с типом B и C. Далее, для всех объектов этого массива вызывается метод Test(). Меня удивляет то, что этот метод вызывается без проблем для всех элементов массива; напомню, что в этом массиве есть и элементы с типом C, в котором данный метод объявлен как приватный. Это вообще нормально?
З.Ы: Я просто эксперементирую...
|
El Scorpio |
04-06-2010 05:56 1427039 |
Цитата:
Цитата Oleg_SK
напомню, что в этом массиве есть и элементы с типом C, в котором данный метод объявлен как приватный. »
|
Ну и что? Указатели всё равно ведь тип А имеют,*а там метод объявлен публичным.
Права доступа к элементам класса проверяются на этапе компиляции, а в процессе выполнения просто происходит только обращение к элементу таблицы виртуальных функций. Если туда будет добавляться ещё и код проверки прав доступа, то программы будут работать ооочень медленно
Поведение программы - нормальное. Ненормален здесь эксперимент :)
|
Появился еще один вопрос: почему, если в классе есть виртуальные функции, компилятор автоматически не делает деструктор этого класса виртуальным? Интересно чем обосновывается такое поведение компилятора; трудно что-ли было это сделать???
|
Цитата:
Цитата Oleg_SK
трудно что-ли было это сделать »
|
а трудно его виртуальным объявить?
мне вот больше нравится когда у интерфейса нет виртуального деструктора (ну не собираюсь я его через указатель разрушать)
|
El Scorpio |
07-06-2010 05:20 1429077 |
Oleg_SK, скорее всего, это недоработка конкретного компилятора
|
Цитата:
Цитата El Scorpio
Oleg_SK, скорее всего, это недоработка конкретного компилятора »
|
El Scorpio, Это не недоработка, это так и нужно (читайте RFC). Виртуальный деструктор должен быть объявлен специально. Чтобы он объявлялся автоматически, нужно чтобы он был объявлен виртуальным в одном из базовых классов.
Код:
class vA
{
virtual ~vA() {clog << "vA::~vA()\n";}
};
class A
{
~A() {clog << "A::~A()\n";}
}
class vB : public vA
{
~vB() {clog << "vB::~vB()\n";}
};
class B : public A
{
~B() {clog << "B::~B()\n";}
}
// испытываем:
vA* va = new vB();
delete va;
// вызовет ~vB(), ~vA()
A* a = new B();
delete a;
// вызовет ~A()
|
Время: 06:28.
© OSzone.net 2001-