我正在解决一个问题,我们有一个接口(interface)类,其中包含实现接口(interface)功能的各种子类。不同的硬件配置将根据配置文件(使用 constexpr
用 C++ 编写)使用最适合它们的子类。
最初,我们的目的是为每个硬件配置使用的类构造函数使用函数指针,直到发现 C++ 中禁止使用指向构造函数的函数指针。我们正在探索这条道路,因为我们想避免全局定义的类。也考虑过使用工厂来允许函数指针,但考虑到我们正在运行的内存受限环境(以及工厂方法动态分配内存的要求),我认为它并不理想。
我们还避免使用宏来选择实现,因为我们不想每次在使用接口(interface)的每个地方创建接口(interface)的新实现时都添加条件编译分支。
例如一些效果:
#if defined(FOO)
Foo object;
#elif defined(BAR)
Bar object;
#elif defined(BAZ)
Baz object;
#endif
此外,我们将有一个场景,其中将实例化可变数量的接口(interface)实例。实例的数量将在编译时根据硬件配置得知,并且应该始终相对较小(< 20)。不幸的是,这排除了(据我所知)宏或 using
声明的使用。
我可能会忽略哪些技术,这些技术可以让我根据要部署到的硬件配置,在配置文件中选择编译时要使用的接口(interface)实现?或者,如果根据我概述的要求这是不可能的,那么我应该考虑什么更好的策略来解决我的问题?
最佳答案
根据我的理解,您可能可以得到 CRTP pattern用于您的界面和子类。在 std::variant
的帮助下,您将能够为您在编译时设置的每个配置拥有一组所需的(变体)实例。假设std::variant
结构不会破坏您的硬件 ROM 要求,因为 sizeof(<variant_type)
将是最大值 sizeof
子类。
#include <iostream>
#include <variant>
#include <array>
// Base interface class
template <typename Derived>
class Base {
public:
void doSomething() {
static_cast<Derived*>(this)->doSomethingImpl();
}
private:
constexpr Base() = default;
friend Derived;
};
// Child class implementations
class Foo : public Base<Foo> {
public:
constexpr Foo() = default;
void doSomethingImpl() {
std::cout << "Foo implementation\n";
}
};
class Bar : public Base<Bar> {
// ....
};
class Baz : public Base<Baz> {
// ....
};
// Change this value to configure the hardware
constexpr short hardwareConfig = 4;
// Implementation selection based on the configuration
template <short Config>
struct InterfaceChooser;
template <>
struct InterfaceChooser<1> {
using Implementation = std::variant<Foo, Bar>;
};
template <>
struct InterfaceChooser<2> {
using Implementation = std::variant<Bar, Baz>;
};
template <>
struct InterfaceChooser<3> {
using Implementation = std::variant<Foo, Baz>;
};
template <>
struct InterfaceChooser<4> {
using Implementation = std::variant<Foo, Bar, Baz>;
};
int main()
{
// Instantiate the interface using the chosen implementation based on the configuration
using Implementation = InterfaceChooser<hardwareConfig>::Implementation;
std::array<Implementation, std::variant_size_v<Implementation>> arrayOfObjects{
Foo{}, Bar{}, Baz{}
};
// Call doSomething() for each object in arrayOfObjects
for (auto& obj : arrayOfObjects) {
std::visit([](auto& object) { object.doSomething(); }, obj);
}
}
更改 hardwareConfig
对于不同的配置,并可能在另一个类模板中实现变体数组,以便可以自定义子成员函数调用。
关于c++ - 如何选择一个类来动态实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76610616/