powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
25 сообщений из 356, страница 1 из 15
virtual methods
    #39647793
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые коллеги объясните плиз

Код: plaintext
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.
class A {
public :
    virtual void m() {
        std::cout << "A\n";
    }

    virtual ~A() {
        std::cout << "~A\n";
    }
};

class B : public A {

public :
    void m() override {
        std::cout << "B\n";
    }

    virtual ~B() {
        std::cout << "~B\n";
    }
};

class C : public B {

public :
    void m() override {
        std::cout << "C\n";
    }

    virtual ~C() {
        std::cout << "~C\n";
    }
};

int main() {
    A *o = new C();
    o->m();
    delete o;
}



Почему
- нет ругани на override без ключевого слова virtual ?
- почему даже не будучи virtual o->m(); все равно дергает метод класса С

Я все время думал что если метод невирутальный то A o дернет метод на классе А.

Поясните плиз тогда зачем вообще оверрайдить метод и снова делать его виртуальным - если вызов и так будет корректным.
...
Рейтинг: 0 / 0
virtual methods
    #39647795
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
semen.s.semen, давай по порядку появления в языке.

1. Сначала было только ключевое слово virtual, которое было обязательлно в базовом классе. Если сигнатура вызова в производном классе совпадала с сигнатурой виртуального метода в базовом классе, то метод был полиморфный. Но для упрощения в производном классе также можно было использовать ключевое слово virtual, чтобы легче читать код (сразу видно, что это общий интерфейс). Но тут существовала проблема: для удобства сделав в производном классе метод virtual и отнаследовавшись от этого производного класса, получали еще один полиморфизм, что не всегда нужно (в твоем случае от В к С).

2. Поэтому в С++11 это "расшили": появилось необязательное (?) ключевое слово override: теперь оно показывает общий интерфейс с базовым классом, а слово virtual- возможность иметь общий интерфейс с производным классом.
...
Рейтинг: 0 / 0
virtual methods
    #39647796
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
...
Рейтинг: 0 / 0
virtual methods
    #39647804
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что virtual необязателен в наследнике. Если метод объявлен virtual в предке то он в наследнике тоже virtual.
...
Рейтинг: 0 / 0
virtual methods
    #39647805
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenЯ все время думал что если метод невирутальный то A o дернет метод на классе А.

У тебя метод m - виртуальный. Каким местом ты думал иначе - непонятно.
http://en.cppreference.com/w/cpp/language/override
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39647830
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так как А объявлен с виртуальным методом, все его потомки будут иметь таблицу виртуальных функций, и там будет m(){}.

Dimitry SibiryakovУ тебя метод m - виртуальный. Каким местом ты думал иначе - непонятно.Класса В у него содержит тот самый метод, но не виртуальный, может поэтому и думал?
...
Рейтинг: 0 / 0
virtual methods
    #39647836
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siemarglsemen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
Это вообще о чём???
...
Рейтинг: 0 / 0
virtual methods
    #39647904
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZSiemarglsemen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
Это вообще о чём???Неверно выразился - если оверрайд, то обязательно и виртуальный тоже.

Ссылка на стандарт на 2 поста выше.
...
Рейтинг: 0 / 0
virtual methods
    #39647932
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglНеверно выразился - если оверрайд, то обязательно и виртуальный тоже.

Ссылка на стандарт на 2 поста выше.
Если удалить из программы все override то суть программы не изменится.
Это просто такой static_assert для виртуальных функций.

А так все правильно
...
Рейтинг: 0 / 0
virtual methods
    #39647940
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen, в общем-то, тебе здесь всё, более-менее, расписали, но я рекомендую тебе рассмотреть свой пример с точки зрения ABI:
1. Компилятор создает три таблицы виртуальных методов для классов A, B и C;
2. В vtable класса A у тебя указатель на "void m()" и указатель на деструктор ~A();
3. В vtable класса B у тебя переопределённый для класса B указатель на "void m()", указатель на ~A() и указатель на ~B();
4. В vtable класса C у тебя переопределённый для класса C указатель на "void m()", указатель на ~A(), указатель на ~B() и указатель на ~C();
5. Создавая экземпляр класса C, первым элементом экземпляра класса, доступным по возвращаемому оператором new указателю, является указатель на таблицу виртуальных методов класса C и никакое стандартное приведение типов его не изменит. Изменить поведение виртуальных функций экземпляра класса можно ( это грязный хак ) только изменив указатель на таблицу виртуальных методов другого класса, например на указатель к VTABLE класса A, но, во-первых, для этого необходимо иметь экземпляр класса A в качестве источника, а во-вторых, при попытке разрушить такой объект, не отработают деструкторы ~C() и ~B(), которые должны освободить ресурсы, захваченные конструкторами при создании экземпляра класса C (в твоём вырожденном примере, конструкторы классов никакие ресурсы, типа памяти из кучи, не захватывают);

Это тебе для баловства (сделай trace в отладчике):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
  typedef void (*PMethodProto)(void*);  // -- (void*) - неявный параметр this
  A* a = new A();
  C* c = new C();
  PMethodProto **pVTBL = reinterpret_cast<PMethodProto**>(c);
  (*pVTBL)[0](pVTBL);
  *pVTBL = *reinterpret_cast<PMethodProto**>(a);
  (*pVTBL)[0](pVTBL);
  delete c;

;-)
...
Рейтинг: 0 / 0
virtual methods
    #39647946
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо
...
Рейтинг: 0 / 0
virtual methods
    #39647947
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?
...
Рейтинг: 0 / 0
virtual methods
    #39647951
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenКстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?Тебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?
...
Рейтинг: 0 / 0
virtual methods
    #39647999
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[offtop]
Ну что, форумяне, теперь вы согласитесь со мной, что для лучшего понимания - как всё работает, изучение программирования лучше начинать с ассемблера и ABI ?
...
Рейтинг: 0 / 0
virtual methods
    #39648022
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenКстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?
Если в предке виртуальный, то неважно уже что там в наследниках - они уже по-любому виртуальные.
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?
Не надо.
rdb_devНу что, форумяне, теперь вы согласитесь со мной, что для лучшего понимания - как всё работает, изучение программирования лучше начинать с ассемблера и ABI ?
Это не всем помогает, как видно
...
Рейтинг: 0 / 0
virtual methods
    #39648030
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Спасибо
...
Рейтинг: 0 / 0
virtual methods
    #39648040
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C.

Не надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648046
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Деструкторы родителя дергаются автоматически

Это я вчера еще прочитал
...
Рейтинг: 0 / 0
virtual methods
    #39648048
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenДеструкторы родителя дергаются автоматически

Это если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648050
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenДеструкторы родителя дергаются автоматически

Это если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.


Расскажите поподробнее плиз
...
Рейтинг: 0 / 0
virtual methods
    #39648058
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovЭто если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.
Если деструктор предка виртуальный то все работает как надо, неважно как удалять.
А виртуальный деструктор предка вообще-то нужно делать всегда если есть виртуальные функции.
...
Рейтинг: 0 / 0
virtual methods
    #39648073
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЕсли в предке виртуальный, то неважно уже что там в наследниках - они уже по-любому виртуальные.
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?Не надо.Ну, забыл я про этот нюанс! Даже не обратил внимания на подсказки IDE NetBeans - значки переопределения на полях.
...
Рейтинг: 0 / 0
virtual methods
    #39648079
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА виртуальный деструктор предка вообще-то нужно делать всегда если есть виртуальные функции.

Да. Но не все это помнят и не все версии компиляторов об этом предупреждают.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648080
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenА понтов то понтов Где ты увидел, что я понтуюсь? :)
Неужели тебе был бесполезен мой пример с указателями на таблицы виртуальных методов?
...
Рейтинг: 0 / 0
virtual methods
    #39648083
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devsemen.s.semenА понтов то понтов Где ты увидел, что я понтуюсь? :)
Неужели тебе был бесполезен мой пример с указателями на таблицы виртуальных методов?

Ну ты отправил меня чего то там проверять вместо того чтобы корректно разобраться

Это я называю понтами

Я и так вчера запускал код и видел как работают деструкторы

Интересно было пообщаться с экспертами
...
Рейтинг: 0 / 0
25 сообщений из 356, страница 1 из 15
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]