Войти

Показать полную графическую версию : Возникла непонятка с виртуальными методами классов


Oleg_SK
03-06-2010, 00:11
В процессе изучения C++ возникла непонятка с виртуальными методами классов. Допустим есть три класса: A, B и C. Классы B и C публично наследуются от класса A. В классе A публичным объявлен виртуальный абстрактный метод Test(). В классах B и С этот метод переопределяется, причем в классе C данный метод объявлен уже как приватный. В функции MAIN создается массив указателей на объекты с типом A, элементам которого присваиваются адреса объектов с типом B и C. Далее, для всех объектов этого массива вызывается метод Test(). Меня удивляет то, что этот метод вызывается без проблем для всех элементов массива; напомню, что в этом массиве есть и элементы с типом C, в котором данный метод объявлен как приватный. Это вообще нормально?

З.Ы: Я просто эксперементирую...

El Scorpio
04-06-2010, 05:56
напомню, что в этом массиве есть и элементы с типом C, в котором данный метод объявлен как приватный. »
Ну и что? Указатели всё равно ведь тип А имеют,*а там метод объявлен публичным.
Права доступа к элементам класса проверяются на этапе компиляции, а в процессе выполнения просто происходит только обращение к элементу таблицы виртуальных функций. Если туда будет добавляться ещё и код проверки прав доступа, то программы будут работать ооочень медленно

Это вообще нормально? »
Поведение программы - нормальное. Ненормален здесь эксперимент :)

Oleg_SK
04-06-2010, 13:04
Появился еще один вопрос: почему, если в классе есть виртуальные функции, компилятор автоматически не делает деструктор этого класса виртуальным? Интересно чем обосновывается такое поведение компилятора; трудно что-ли было это сделать???

pva
04-06-2010, 18:18
трудно что-ли было это сделать »
а трудно его виртуальным объявить?
мне вот больше нравится когда у интерфейса нет виртуального деструктора (ну не собираюсь я его через указатель разрушать)

El Scorpio
07-06-2010, 05:20
Oleg_SK, скорее всего, это недоработка конкретного компилятора

pva
12-06-2010, 09:35
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()




© OSzone.net 2001-2012