Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
John Paramol
0 / 0 / 0
Регистрация: 14.05.2008
Сообщений: 19
#1

Проблема с виртуальными функциями - C++

02.07.2008, 16:06. Просмотров 1225. Ответов 6
Метки нет (Все метки)

Привет.
Столкнулся с небольшой проблемой, касательно виртуальных функций.
Стыдно спрашивать, ибо это нечто элементарное.
Просто я уже успел подзабыть основы ООП в C++.
Вот пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
class A
{
  public:
    void Func()
    {
      VirtFunc();
    }
    ~A()
    {
      Destroy();
    }
    virtual void VirtFunc()
    {
      puts("A::VirtFunc() called");
    }
    virtual void Destroy()
    {
      puts("A::Destroy() called");
    }
};
class B : public A
{
  public:
    virtual void VirtFunc()
    {
      puts("B::VirtFunc() called");
    }
    virtual void Destroy()
    {
      puts("B::Destroy() called");
    }
};
int main()
{
  {
    B BObject;
    BObject.Func();
  }
  getchar();
  return 0;
}
В методе Func вызывается виртуальная функция VirtFunc из наследника - так и надо.
Но в деструкторе наследника почему-то вызывается виртуальная функция Destroy из родителя.
Мне нужно при разрушении наследника вызвать Destroy наследника.
Где я туплю?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.07.2008, 16:06     Проблема с виртуальными функциями
Посмотрите здесь:

C++ Удаление узла бинарного дерева, проблема с функциями, адресацией
РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ C++
C++ OpenGL, проблема с функциями.
проблема со структурой и функциями C++
C++ Задачка с наследованием и виртуальными функциями
C++ Создать абстрактный базовый класс с виртуальными методами вычисления функции y в заданной точке х
C++ можно ли делать виртуальными перегружаемые операторы?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Lord_Voodoo
Супер-модератор
8510 / 2177 / 61
Регистрация: 07.03.2007
Сообщений: 10,854
Завершенные тесты: 1
02.07.2008, 16:28     Проблема с виртуальными функциями #2
по идее, тебе надо переопределить деструктор для наследника, в противном случае он наследует деструктор родителя, поэтому его и вызывает...
John Paramol
0 / 0 / 0
Регистрация: 14.05.2008
Сообщений: 19
02.07.2008, 16:35  [ТС]     Проблема с виртуальными функциями #3
Ну так в деструкторе родителя вызывается Destroy, а он - виртуальный. По идее должен быть вызван B:estroy(), но вызывается A:estroy()...
Lord_Voodoo
Супер-модератор
8510 / 2177 / 61
Регистрация: 07.03.2007
Сообщений: 10,854
Завершенные тесты: 1
02.07.2008, 16:40     Проблема с виртуальными функциями #4
нет, как раз таки вызывается родительский деструктор, потому что для наследника не определен деструктор, поэтому и перемещаешься по иерархии вверх... хотя глянул твой код, он все равно по иерархии вверх идет, даже с объявленным конструктором...
в билдеровском хелпе написано, что оно так и должно быть, обращение к деструкторам идет до базового класса...
Код
#include <iostream>
class color {
public:
   virtual ~color() {  // Virtual destructor
      std::cout << "color dtor\n";
      }
};
class red : public color {
public:
   ~red() {  // This destructor is also virtual
      std::cout << "red dtor\n";
      }
};
class brightred : public red {
public:
   ~brightred() {  // This destructor is also virtual
       std::cout << "brightred dtor\n";
       }
};
int main() {
   color *palette[3];
   palette[0] = new red;
   palette[1] = new brightred;
   palette[2] = new color;
   // The destructors for red and color are called.
   delete palette[0];
   std::cout << std::endl;
   // The destructors for bright red, red, and color are called.
   delete palette[1];
   std::cout << std::endl;
   // The destructor for color is called.
   delete palette[2];
   return 0;
}
Program Output:
red dtor
color dtor
brightred dtor
red dtor
color dtor

color dtor
в codeblock та же ситуация:
Код
#include <stdio.h>
class A
{
    private:
    virtual void Destroy()
    {
      puts("A::Destroy() called");
    }
    public:
    virtual void Func()
    {
      VirtFunc();
    }
    ~A()
    {
      Destroy();
    }
    virtual void VirtFunc()
    {
      puts("A::VirtFunc() called");
    }
};
class B : public A
{
  public:
    ~B()
    {
        Destroy();
    }
    virtual void Func()
    {
      puts("B::VirtFunc() called");
    }
    virtual void Destroy()
    {
      puts("B::Destroy() called");
    }
};
class C : public B
{
  public:
    ~C()
    {
        Destroy(0);
    }
    virtual void Func()
    {
      puts("C::VirtFunc() called");
    }
    void Destroy(int i)
    {
      puts("C::Destroy() called");
    }
};
int main()
{
  {
    C BObject;
    BObject.Func();
  }
  getchar();
  return 0;
}
John Paramol
0 / 0 / 0
Регистрация: 14.05.2008
Сообщений: 19
02.07.2008, 17:41  [ТС]     Проблема с виртуальными функциями #5
Пожалуйста, читайте повнимательнее.
Это понятно, что деструктор вызывается родительский, т.к. он наследуется. Но в нем вызывается метод Destroy(), а он - виртуальный, и поэтому должен быть вызван Destroy() наследника, а не родителя.
Но выходит наоборот:(
Lord_Voodoo
Супер-модератор
8510 / 2177 / 61
Регистрация: 07.03.2007
Сообщений: 10,854
Завершенные тесты: 1
02.07.2008, 17:44     Проблема с виртуальными функциями #6
а с чего вы взяли, что деструкторе класса А будет вызываться функция наследника - класса В?
разве наследствие идет не нисходящее? а если вызывается деструктор класса А, то соответственно и функция класса А...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.07.2008, 08:55     Проблема с виртуальными функциями
Еще ссылки по теме:

зачем может понадобиться делать операторы виртуальными? C++
C++ Создать абстрактный базовый класс с виртуальными функциями - площадь и периметр
Шаблонный класс: для чего методы объявлены виртуальными, если нет наследования? C++
Какие функции не могут быть виртуальными? C++
Классы с виртуальными функциями. Class Student C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
John Paramol
0 / 0 / 0
Регистрация: 14.05.2008
Сообщений: 19
03.07.2008, 08:55  [ТС]     Проблема с виртуальными функциями #7
Цитата Сообщение от WooDooMan666 Посмотреть сообщение
а с чего вы взяли, что деструкторе класса А будет вызываться функция наследника - класса В?
фффф... с того, что она виртуальная.
В общем, мне уже подсказали ответ: в конструкторах/деструкторах виртуальные функции ведут себя как обычные.
Yandex
Объявления
03.07.2008, 08:55     Проблема с виртуальными функциями
Ответ Создать тему
Опции темы

Текущее время: 09:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru