union
в основном требуется только для реализации variant
.
Так что вы можете использовать:
using DRIVER = std::variant<std::unique_ptr<DrvClassA>,
std::unique_ptr<DrvClassB>,
std::unique_ptr<DrvClassC>>;
// or
//using DRIVER = std::variant<DrvClassA*, DrvClassB*, DrvClassC*>;
с использованием
DRIVER Drv;
// ...
Drv = std::make_unique<DrvClassA>(args);
// ...
std::visit(overloaded{[](const std::unique_ptr<DrvClassA>& ptr){ ptr->funcA(); },
[](const auto& ptr){ ptr->common_interface(); }}, // DrvClassB or DrvClassC
Drv);
Но полиморфизм может быть более подходящим:
struct DRIVER
{
virtual ~DRIVER() = default;
virtual void some_common_function() = 0;
};
struct DrvClassA : DRIVER
{
void some_common_function() override { /*..*/ }
};
struct DrvClassB : DRIVER
{
void some_common_function() override { /*..*/ }
};
struct DrvClassC : DRIVER
{
void some_common_function() override { /*..*/ }
};
, а затем
std::unique_ptr<DRIVER> Drv;
// ...
Drv = std::make_unique<DrvClassA>(args);
Drv->some_common_function();