gpt4 book ai didi

c++ - 静态接口(interface) - CRTP?混合?其他?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:02:43 24 4
gpt4 key购买 nike

我对接口(interface)实现很感兴趣。我知道这样做的标准方法是编写一个具有纯虚拟方法的类,该类将用作接口(interface),例如:

class Interface {
public:
virtual void doSometing() = 0;
}

并使用它:

class Implementation : public Interface {
public:
virtual void doSomething() override { ... }
}

或者甚至更好地应用 NVI(非虚拟接口(interface))。

但是所有这些都使用我试图避免的虚函数 - 因为我正在为嵌入式编码,其中必须考虑由于 vtable 间接寻址导致的性能损失。

因此我专注于“静态多态性”并尝试使用 CRTP 来实现接口(interface):

template<typename T>
class Interface {
public:
void doSomething() {
static_cast<T&>(*this)._doSomething();
}

class Implementation : public Interface<Implementation> {
public:
void _doSomething() { /* Do implementation specific stuff here */ }
}

class Implmentation2 : public Interface<Implementation2> {...}

到目前为止一切顺利。但我看到了一个大麻烦。一旦我想存储一堆指向某个容器接口(interface)的指针并想访问各种实现类的实例,我就会遇到麻烦 Interface<T>本身总是一个不同的类,而不是一个接口(interface):

Interface<Implementation>Interface<Implementation2>是不同的类型。

好吧,让我们创建一个公共(public)基类来从...派生接口(interface)

template<typename T>
class Interface : public IfaceBase {
public:
void doSomething() {
static_cast<T&>(*this)._doSomething();
}

...但是我无法使用该接口(interface)访问最终实例。在我看来,我正在尝试创建一个接口(interface),这个接口(interface)本身听起来很疯狂......

所以我发现 CRTP 在这种情况下不太有用。我在网上搜索了一下,发现 MIXIN 似乎是“CRTP 颠倒了”。但是我不确定它是否可以用于我的目的...

你能帮帮我吗?如果有一种方法可以应用 MIXINS 或任何其他习语/任何东西来拥有没有虚拟的 C++ 接口(interface),请分享这个想法:)

非常感谢任何愿意提供帮助的人!干杯马丁

最佳答案

我知道两种以多态方式从不同类型调用非虚拟方法的方法:

  1. 类型删除:将非虚拟类包装到其他具有虚拟方法的类中(这与您尝试的比较接近)。
  2. 应用于 variant 类型的访问者模式。这需要在调用方法的编译时知道所有类型。

因为您根本不需要虚拟方法,所以我将只解释解决方案 2。如果您对类型删除更感兴趣,C++ 'Type Erasure' Explained (Dave Kilian's blog)是一本好书。

访问者模式和变体类型 (C++17)

假设您的类型具有非虚方法:

class Implementation1 {
void doSomething() { /* ... */ }
};

class Implementation2 {
void doSomething() { /* ... */ }
};

您可以使用 std::variant 将它们的任意组合存储在一个容器中:

// #include <variant>
// #include <vector>
using ImplVariant = std::variant<Implementation1,Implementation2>;
std::vector<ImplVariant> array = {Implementation2(), Implementation1() /*, ...*/};

要在 MyVariant 对象上调用 doSomething,您需要为其应用一个访问者。这在 C++17 中只需传递一个 generic lambda 即可完成。至 std::visit :

for (auto& variant : array) {
std::visit([](auto&& object) { object.doSomething(); }, variant);
}

Live demo

或者,您可以创建(智能)指针的变体

关于c++ - 静态接口(interface) - CRTP?混合?其他?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56660709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com