Создана ли здесь виртуальная таблица?
Да, так как у вас есть virtual
функций-членов.
Имеет ли для меня значение, создана виртуальная таблица или нет, поскольку я ее не использую?
Поскольку вы ее не используете, она по-прежнему имеет значение в том смысле, что она увеличит размер вашей структуры Derived
.
Здесь ваша структура Derived
имеет размер 8. Но без vtable она будет иметь размер 1.
Может быть, есть другой способ убедиться, что компилятор жалуется, если Derived
не реализует f()
?
Честно говоря, я думаю, что ваше решение, использующее Base
в качестве интерфейса, чтобы заставить каждый производный класс реализовать функцию f()
, совершенно нормально, поскольку это точный вариант использования интерфейсов.
Но если вас беспокоит размер структуры Derived
(потому что вы сказали, что хотите создавать ее экземпляры миллионы раз), возможно, вас заинтересует std::is_member_function_pointer
признак типа.
Я понятия не имею, как вы собираетесь создать свою структуру Derived
, поэтому я не могу предоставить код, который точно соответствовал бы вашим потребностям.
Но идея, о которой я думаю, эквивалентна следующему (общий пример):
#include <type_traits>
template <typename T>
void instantiate_a_lot_of_times(std::size_t nb_times)
{
// Check if the f() member function exists
static_assert(std::is_member_function_pointer<decltype(&T::f)>::value, "Error: The T::f() member function must be defined");
for(std::size_t i = 0; i < nb_times; ++i)
{
T t;
// Do something with t
}
}
Но имейте в виду, что у этого подхода есть недостаток, заключающийся в задержке проверки.
Компиляция завершится ошибкой не при обнаружении определения структуры, а при оценке static_assert
.
person
Fareanor
schedule
17.01.2020
f()
вBase
? ЕслиDerived
не реализуетf()
,obj.f()
не скомпилируется. - person Evg   schedule 17.01.2020Derived
. В моем случае это было 8 байт, что подразумевает указатель на виртуальную таблицу. Возможно, есть другой способ убедиться, что компилятор жалуется, еслиDerived
не реализуетf()
? Конечно, если вы вызоветеf
для любого объектаDerived
без указанияf
, компиляция завершится ошибкой. Также посмотрите: Можно ли написать шаблон для проверки существования функции?. Вы можете написать метафункцию для проверки существованияf
и использовать ее, например, со статическим утверждением для лучшей диагностики. - person Daniel Langr   schedule 17.01.2020static_cast<derived>(this)->f()
приведет к ошибке времени компиляции. Существует расширенный способ создания CRTP, который обеспечивает резервную функцию, но не является частью шаблона. - person Swift - Friday Pie   schedule 17.01.2020