问题
Chapter 16.4 Parameterized Virtuality in the C++ Templates - The Complete Guide, by David Vandevoorde and Nicolai M. Josuttis, says:
C++ allows us to parameterize directly three kinds of entities through templates: types, constants ("nontypes"), and templates. However, indirectly, it also allows us to parameterize other attributes such as the virtuality of a member function.
The following code was illustrated in that chapter:
#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;
}
Example online: https://rextester.com/OAGC66937
I understand the usage of such a technique, but unfortunately the book does not provide any further details as to how this thing happens. I can see that Base
is actually a derived class inheriting from the template parameter T
.
Questions:
- What happens in the background during parameterized virtuality?
- Does something happen in the resulting v_table?
- How does the
virtual
from the template parameter get transferred over?
回答1:
To expand upon @Quentin's comment
Once the Base template is specialized for a specific T, everything proceeds as usual through inheritance and virtual overriding.
Let's write out an equivalent non-template set of classes
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;
}
See it live
What happens in the background during parameterized virtuality?
Base<T>
inherits from T
, and follows the rules of inheritance
Does something happen in the resulting v_table?
Only the ordinary virtual
mechanisms. Specifically, in the NotVirtual
case there aren't any virtual functions, so there probably won't be any vtables.
How does the virtual from the template parameter get transferred over?
By the normal rules of inheritance
来源:https://stackoverflow.com/questions/55472947/what-happens-in-parameterized-virtuality