Реализация функции-члена, обеспечивающей накладные расходы - PullRequest
3 голосов
/ 17 января 2020

У меня есть класс Base и класс Derived. Единственная цель класса Base - убедиться, что Derived реализует функцию-член.

struct Base
{
    virtual void f() = 0;
};

struct Derived : Base
{
    void f() override final {}
};

Я не использую этот класс полиморфно, т. Е. Просто создаю экземпляры объектов типа Derived в стеке, например:

Derived obj;

, и мне нужно сделать это миллионы раз.

Редактировать : одновременно существует только несколько экземпляров ( без переполнения стека).

Здесь создается vtable (наверное, во время компиляции)? Имеет ли значение для меня, если vtable создан или нет, так как я не использую его (или я как-то)? Есть ли какие-либо накладные расходы, которые я должен рассмотреть, используя этот дизайн? Может быть, есть другой способ убедиться, что компилятор жалуется, если Derived не реализует f()?

1 Ответ

3 голосов
/ 17 января 2020

Здесь создается vtable?

Да, поскольку у вас есть virtual функций-членов.

Имеет ли значение для меня, если создается vtable или нет, , поскольку я им не пользуюсь ?

Поскольку вы не используете его, все равно имеет значение в том смысле, что он увеличит размер вашего Derived структура. Здесь ваша Derived структура имеет размер 8. Но без vtable она будет иметь размер 1.

Может быть, есть другой способ убедиться, что компилятор пожалуется, если Derived не реализовать f()?

Если честно, я думаю, что ваше решение, использующее Base в качестве интерфейса для того, чтобы заставить каждый производный класс реализовать функцию f(), вполне нормально, так как это точный сценарий использования интерфейсов .


Но если размер структуры Derived вызывает беспокойство (потому что вы сказали, что хотите создать его миллион раз ), возможно, вас заинтересует признак типа std::is_member_function_pointer.

Я понятия не имею, как вы намереваетесь создать экземпляр структуры Derived, поэтому я не могу предоставить код, который бы точно соответствует вашим потребностям. Но идея, о которой я думаю, эквивалентна следующему (пример generi c):

 #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.

...