根据不同的类型,联盟成员仅在一个类中
Union members exclusively in a class depending on different types
我正在实现一个类,其中每个实例化都有一个句柄,该句柄将完全依赖于成员type
。不同的类型与不同的句柄相关联。
enum class Type {
TypeA, TypeB, TypeC;
};
class HandleA { ... };
class HandleB { ... };
class HandleC { ... };
class Foo {
public:
Type type;
std::unique_ptr<HandleA> handleA;
std::unique_ptr<HandleB> handleB;
std::unique_ptr<HandleC> handleC;
};
理想情况下,如果类型为TypeA
,则存在handleA
;如果类型为TypeB
,则存在handleB
;如果类型是TypeC
,则存在handleC
。然而,我认为应该有一个更好的设计模式。否则,我的类型越多,类Foo
中占用的unique_ptr
就越多。我知道union
可能是一个很好的解决方案,但我想知道是否存在更具可扩展性的c++
或c++11
解决方案。由于Foo可能以虚拟的方式用于其他派生类,这些派生类将采用不同的构造函数,所以我不想寻找模板化的解决方案。
我一直在研究需求,发现这里要解决的基本问题是:如何在运行时选择类型。
其他一切都可以用一点模板魔法来解决——在Foo本身不应该是模板的情况下,这种魔法就失败了。
那么,任何克服这个问题的技巧(我们可以用成员函数指针做一些令人惊叹的事情)似乎只会让我们重新实现已经免费提供的VTable间接虚拟函数。在这种考虑下,我倾向于遵循@RobK:的评论
#include <iostream>
#include <memory>
#include <string>
enum class Type { TypeA, TypeB, TypeC };
class Handle
{
public:
// virtual ~Handle() = default; // if any subclass is not empty
virtual std::string sing() const = 0; // purely virtual function
};
class HandleA : public Handle { public: std::string sing() const { return "Aaha"; } };
class HandleB : public Handle { public: std::string sing() const { return "Behe"; } };
class HandleC : public Handle { public: std::string sing() const { return "Cehe"; } };
class Foo
{
Type type;
std::unique_ptr<Handle> handle;
public:
constexpr Foo(Type newType) : type{newType}, handle()
{
switch(newType) // establishes the mapping between Type and Handle-subclass
{
case Type::TypeA: this->handle.reset(new HandleA()); return;
case Type::TypeB: this->handle.reset(new HandleB()); return;
case Type::TypeC: this->handle.reset(new HandleC()); return;
}
}
// virtual function call automatically resolves to used subclass
void showHandle() const { std::cout << this->handle->sing() << std::endl; }
};
int main()
{
Foo fooA(Type::TypeA);
Foo fooB(Type::TypeB);
Foo fooC(Type::TypeC);
fooA.showHandle();
fooB.showHandle();
fooC.showHandle();
}
请注意,当以这种方式使用不完整的类型(如我的句柄)时,需要记住以下几点:
- 如果任何子类定义了自己的非静态成员对象,Handle和所有子类都必须接收一个声明的虚拟析构函数。
- 如果没有,对此类子类的对象的销毁是不完整的,并且会泄漏内存
- 就像Handle中注释掉的析构函数一样,这些可以是默认值
- 不重写纯虚拟函数(如我的Handle::sing)然后调用它将立即终止程序
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 更改可变参数模板中的最后一个类型
- 如何构造一个类型特征,可以判断一个类型的私有方法是否可以在另一个类型的构造函数中调用?
- 有没有办法同时将一个类型分配给C++中的多个模板?
- C++:可以模板化一个类型名称吗
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 给定一个类型为 Container:<T>:Iterator 的函数参数,如何为某些类型的 T 实现特定的重载?
- 期望一个类型,得到一个模板
- 初始化一个类型向量的巨大向量<int>
- 我可以使用预处理器将一个类型声明替换为另一个类型声明吗?
- 具有多种类型的类数组?如何访问数组中的一个类型
- Opencv C++ 声明一个类型为 uint8 的矩阵
- 模板参数列表中只有一个类型名称是什么意思?
- C++模板部分特化:为什么我无法匹配可变参数模板中的最后一个类型
- 为什么我们有一个类型不匹配
- 在函数模板中将一个类型名映射到另一个类型名
- 创建一个类型bool的向量,其中所有值均可初始化为true
- 在C API中定义了一个类型,如何将其与命名空间中的C++类相关联