【发布时间】:2023-02-02 19:30:22
【问题描述】:
我想知道如果我从不从基类调用函数(即虚拟分派),那么使用 CRTP 是否比虚拟函数多态性有任何好处?
这是示例代码。反汇编可以在https://godbolt.org/z/WYKaG5bbG找到。
struct Mixin {
virtual void work() = 0;
};
template <typename T>
struct CRTPMixin {
void call_work() {
static_cast<T*>(this)->work();
}
};
struct Parent {};
struct Child : Parent, Mixin, CRTPMixin<Child> {
int i = 0;
void work() override {
i ++;
}
};
Child child;
Mixin& mixin = child;
int main() {
child.work();
mixin.work();
child.call_work();
}
我发现如果我从child或通过CRTPMixin接口调用虚函数work,反汇编代码是一样的,只有静态的call。如果我在Mixin& mixin = child 上调用该函数,则会发生虚拟分派,并且会为此操作生成更多指令。
我的问题是,如果我正在设计接口/mixin 类型的结构,我将只调用派生类,而不是基类,那么在任何情况下 CRTP 会比 virutal 函数方法受益更多吗?
谢谢!
【问题讨论】:
-
你的例子混合了这两个概念,你真的应该有虚拟方法或 ctrp/mixin 才能真正看到区别。所以你要么有一个从 Mixin 派生的子类,要么从 CrtpMixin 派生,而不是两者。最后,静态多态性必须产生没有虚拟调用的代码。
-
@PepijnKramer 通常 mixins 调用派生类的一些函数,否则这样的“mixin”可以只是普通的基类,不需要虚函数或 CRTP。
-
@sklott 你是对的。
标签: c++ polymorphism virtual-functions crtp static-polymorphism