C++ 对象指针的并集(仅对不同实例使用一种类型)
我现在在一个类中创建了以下代码snipplet:C++ 对象指针的并集(仅对不同实例使用一种类型),c++,object,union,C++,Object,Union,我现在在一个类中创建了以下代码snipplet: DrvClassA *drv_a_obj; DrvClassB *drv_b_obj; DrvClassC *drv_c_obj; if ( use_drv_a ) { drv_a_obj = new DrvClassA(args); } if ( use_drv_b ) { drv_b_obj = new DrvClassB(args); } if ( use_drv_c ) { drv_c_obj = new DrvCla
DrvClassA *drv_a_obj;
DrvClassB *drv_b_obj;
DrvClassC *drv_c_obj;
if ( use_drv_a ) {
drv_a_obj = new DrvClassA(args);
}
if ( use_drv_b ) {
drv_b_obj = new DrvClassB(args);
}
if ( use_drv_c ) {
drv_c_obj = new DrvClassC(args);
}
并希望以某种方式进行转换,以便仅为创建的驱动程序实例使用一个变量:
this->Drv = new DrvClassA(args);
}
if ( use_drv_b ) {
this->Drv = new DrvClassB(args);
}
if ( use_drv_c ) {
this->Drv = new DrvClassC(args);
}
我曾想过创建一个这样的联合体,但在编译时出现了错误
错误:无法将分配中的“DrvClassA*”转换为“MainClass::DRIVERS*”
这是可以实现的吗?我遗漏了什么?您可能正在寻找的是: 最好使用智能指针来避免内存泄漏:
是的,您可以拥有指针的并集 我错过了什么 您未能指定要分配的联合成员。正确语法:
this->Drv->drv_a_obj = new DrvClassA(args);
顺便说一句,你以后可能会对分配的工会成员感兴趣。你会发现这是不可能的。解决方案是使用一个标记的联合,例如std::variant
另一个可能更好的设计是使用继承。此->Drv可以是指向基本对象的指针,而不是联合
p.p.p.S.不要使用拥有裸指针。最终会导致内存泄漏和未定义的行为。改用RAII容器和智能指针。只有在实现变量时才需要union
因此,您可以使用:
using DRIVER = std::variant<std::unique_ptr<DrvClassA>,
std::unique_ptr<DrvClassB>,
std::unique_ptr<DrvClassC>>;
// or
//using DRIVER = std::variant<DrvClassA*, DrvClassB*, DrvClassC*>;
然后
std::unique_ptr<DRIVER> Drv;
// ...
Drv = std::make_unique<DrvClassA>(args);
Drv->some_common_function();
如果我使用这个->Drv->Drv_a_obj,那么我将无法调用像这样创建的类的函数->Drv->setOptionarg,是吗?我认为,留给我的唯一选择是使用继承,@V1pr确实不是。您需要使用此->Drv->Drv_a_obj->设置选项Arg
this->Drv->drv_a_obj = new DrvClassA(args);
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();