Что происходит в параметризованной виртуальности? - PullRequest
0 голосов
/ 02 апреля 2019

Глава 16.4 Параметризованная виртуальность в шаблонах C ++ - Полное руководство , написанное Дэвидом Вандеворде и Николаем М. Йосуттисом, гласит:

C ++ позволяетМы можем напрямую параметризовать три вида сущностей через шаблоны: типы, константы («нетипы») и шаблоны.Однако косвенно это также позволяет нам параметризировать другие атрибуты, такие как виртуальность функции-члена.

В этой главе проиллюстрирован следующий код:

#include <iostream>

struct NotVirtual
{};

struct IsVirtual
{
    virtual void func() {;}
};

//---------------------//

template<typename T>
struct Base : T
{
    void func()
    { std::cout<< "Base::func()" <<std::endl; }
};

template<typename T>
struct Derived : Base<T>
{
    void func()
    { std::cout<< "Derived::func()" <<std::endl; }
};

//---------------------//

int main()
{
    Base<NotVirtual> *p1 = new Derived<NotVirtual>();
    p1->func();
    delete p1;

    Base<IsVirtual> *p2 = new Derived<IsVirtual>();
    p2->func();
    delete p2;
}

Пример онлайн: https://rextester.com/OAGC66937

Я понимаю, как использовать такую ​​технику, но, к сожалению, в книге нет подробностей о том, как это происходит.Я вижу, что Base на самом деле является производным классом, унаследованным от параметра шаблона T.

Вопросы:

  1. Что происходит в фоновом режиме во времяпараметризованная виртуальность?
  2. Что-то происходит в результирующей v_table?
  3. Как передается virtual из параметра шаблона?

1 Ответ

3 голосов
/ 02 апреля 2019

Расширить комментарий @ Квентина

Как только базовый шаблон специализируется для определенного T, все происходит как обычно с помощью наследования и виртуального переопределения.

Выпишем эквивалентный не шаблонный набор классов

struct BaseNV : NotVirtual
{
    void func() // first definition of func
    { std::cout<< "Base::func()" <<std::endl; }
};

struct DerivedNV : BaseNV 
{
    void func() // hides BaseNV::func
    { std::cout<< "Derived::func()" <<std::endl; }
};

struct BaseIV : IsVirtual
{
    void func() // implicitly virtual, overrides IsVirtual::func
    { std::cout<< "Base::func()" <<std::endl; }
};

struct DerivedIV : BaseIV
{
    void func() // implicitly virtual, overrides BaseIV::func (and IsVirtual::func)
    { std::cout<< "Derived::func()" <<std::endl; }
};

int main()
{
    BaseNV *p1 = new DerivedNV();
    p1->func();
    delete p1;

    BaseIV *p2 = new DerivedIV();
    p2->func();
    delete p2;
}

Посмотреть вживую

Что происходит в фоновом режиме во время параметризованной виртуальности?

Base<T> наследуется от T и следует правилам наследования

Что-то происходит в результирующей v_table?

Только обычные virtual механизмы. В частности, в NotVirtual случае не виртуальных функций, поэтому, вероятно, не будет никаких vtables.

Как передается виртуальный из параметра шаблона?

По обычным правилам наследования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...