C ++模板-完整指南中的<16.4章<参数化虚拟化,由David Vandevoorde和Nicolai M. Josuttis说道:
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
的派生类。
问题:
virtual
转移过来?答案 0 :(得分:3)
扩展@Quentin的评论
一旦Base模板专用于特定的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
情况下,没有任何虚拟函数,因此可能不会有任何vtable。
模板参数中的虚拟如何转移?
按照正常的继承规则