Сообщение Re[12]: Книжка по UB от 13.08.2025 14:54
Изменено 13.08.2025 14:58 so5team
Re[12]: Книжка по UB
Здравствуйте, watchmaker, Вы писали:
W>Тогда, если быть последовательным, придётся принять утверждение: "в final-классах виртуальная диспетчеризация не работает". Как думаешь, хорошее и полезное это утверждение, чтобы его запоминать?
Тут требуется пояснительная бригада ибо аппеляцию к final-классам не понял от слова совсем.
Я выше дал определение для виртуальности: "виртуальность в том и состоит, что мы дергаем метод через указатель/ссылку на базовый класс, а получаем вызов кода из производного класса"
Берем пример:
цынк
И видим внутри call то, о чем я пишу: по ссылке на базовый класс вызывается f(). При этом по факту вызвается f из наследника. Вне зависимости от final или не-final.
Тогда как в конструкторе base у нас this указывает на base, по this вызывается f(), но это не f() из наследников.
Т.е. в данном случае виртуальности у вызова нет. ЧТД.
W>Тогда, если быть последовательным, придётся принять утверждение: "в final-классах виртуальная диспетчеризация не работает". Как думаешь, хорошее и полезное это утверждение, чтобы его запоминать?
Тут требуется пояснительная бригада ибо аппеляцию к final-классам не понял от слова совсем.
Я выше дал определение для виртуальности: "виртуальность в том и состоит, что мы дергаем метод через указатель/ссылку на базовый класс, а получаем вызов кода из производного класса"
Берем пример:
#include <iostream>
class base
{
public:
base() {
std::cout << "base {" << std::endl;
f();
std::cout << "base }" << std::endl;
}
virtual void f() { std::cout << "base::f" << std::endl; }
};
void call(base & b) { b.f(); }
class derived : public base
{
void f() override { std::cout << "derived::f" << std::endl; }
public:
derived() = default;
};
class another_derived final : public base
{
void f() override { std::cout << "another_derived::f" << std::endl; }
public:
another_derived() = default;
};
int main()
{
derived d;
another_derived ad;
std::cout << "---" << std::endl;
call(d);
call(ad);
}
цынк
И видим внутри call то, о чем я пишу: по ссылке на базовый класс вызывается f(). При этом по факту вызвается f из наследника. Вне зависимости от final или не-final.
Тогда как в конструкторе base у нас this указывает на base, по this вызывается f(), но это не f() из наследников.
Т.е. в данном случае виртуальности у вызова нет. ЧТД.
Re[12]: Книжка по UB
Здравствуйте, watchmaker, Вы писали:
W>Тогда, если быть последовательным, придётся принять утверждение: "в final-классах виртуальная диспетчеризация не работает". Как думаешь, хорошее и полезное это утверждение, чтобы его запоминать?
Тут требуется пояснительная бригада ибо аппеляцию к final-классам не понял от слова совсем.
Я выше дал определение для виртуальности: "виртуальность в том и состоит, что мы дергаем метод через указатель/ссылку на базовый класс, а получаем вызов кода из производного класса"
Берем пример:
цынк
И видим внутри call то, о чем я пишу: по ссылке на базовый класс вызывается f(). При этом по факту вызвается f из наследника. Вне зависимости от final или не-final.
Тогда как в конструкторе base у нас this указывает на base, по this вызывается f(), но это не f() из наследников.
Т.е. в данном случае (т.е. внутри конструктора) виртуальности у вызова нет. ЧТД.
W>Тогда, если быть последовательным, придётся принять утверждение: "в final-классах виртуальная диспетчеризация не работает". Как думаешь, хорошее и полезное это утверждение, чтобы его запоминать?
Тут требуется пояснительная бригада ибо аппеляцию к final-классам не понял от слова совсем.
Я выше дал определение для виртуальности: "виртуальность в том и состоит, что мы дергаем метод через указатель/ссылку на базовый класс, а получаем вызов кода из производного класса"
Берем пример:
#include <iostream>
class base
{
public:
base() {
std::cout << "base {" << std::endl;
f();
std::cout << "base }" << std::endl;
}
virtual void f() { std::cout << "base::f" << std::endl; }
};
void call(base & b) { b.f(); }
class derived : public base
{
void f() override { std::cout << "derived::f" << std::endl; }
public:
derived() = default;
};
class another_derived final : public base
{
void f() override { std::cout << "another_derived::f" << std::endl; }
public:
another_derived() = default;
};
int main()
{
derived d;
another_derived ad;
std::cout << "---" << std::endl;
call(d);
call(ad);
}
цынк
И видим внутри call то, о чем я пишу: по ссылке на базовый класс вызывается f(). При этом по факту вызвается f из наследника. Вне зависимости от final или не-final.
Тогда как в конструкторе base у нас this указывает на base, по this вызывается f(), но это не f() из наследников.
Т.е. в данном случае (т.е. внутри конструктора) виртуальности у вызова нет. ЧТД.