我在玩C++中的多态性,我发现了std::variant。然而,它似乎不是很高的性能,也不是编码友好,在大多数情况下,你必须使用虚拟基类。
所以我“重新发明”了标记联合,它允许你存储多个类,并允许你几乎直接根据存储的类型调用它们的成员函数。
假设我有以下包含具有相同签名的方法的类:
struct A {
void print() { printf("A"); }
char id() { return 'A'; }
};
struct B {
void print() { printf("B"); }
char id() { return 'B'; }
};
struct C {
void print() { printf("C"); }
char id() { return 'C'; }
};
struct D {
void print() { printf("D"); }
char id() { return 'D'; }
};
现在我有一个tagged_union类,它包含所有类的union沿着存储的类型id,并使用内部switch实现它们的方法(不是真实的的用例,只是一个例子,我真的在光线跟踪器中使用它来存储不同的基本网格):
struct tagged_union{
tagged_union(){}
tagged_union(A val): a(val), type(0) {}
tagged_union(B val): b(val), type(1) {}
tagged_union(C val): c(val), type(2) {}
tagged_union(D val): d(val), type(3) {}
void print() {
switch(type){
case 0: a.print(); break;
case 1: b.print(); break;
case 2: c.print(); break;
case 3: d.print(); break;
default: break;
}
}
char id() {
switch(type){
case 0: return a.id(); break;
case 1: return b.id(); break;
case 2: return c.id(); break;
case 3: return d.id(); break;
default: return 0;
}
}
private:
union{
A a;
B b;
C c;
D d;
};
int type;
};
现在我的问题是是否可以使定义并集的过程自动化(例如,变量模板+递归定义成员),并在运行时在成员函数中选择正确的存储类型,而不必为每个成员函数写出switch?
我为任何语法错误和不正确的术语道歉,因为我不是一个母语人士。
编辑:我已经清楚了,你不必使用virtual来从variant调用多态函数,但是我仍然出于好奇而坚持最初的问题。
2条答案
按热度按时间cl25kdpy1#
因此,存储在一个变体中的四个类将是
std::variant<A, B, C, D>
。例如,创建这些对象的向量并调用每个对象的
print
成员函数的代码可能如下所示:使用每一个的
id()
将是类似的,除了(当然)用o.id()
替换o.print()
。不确定在什么情况下可以将虚拟继承与
std::variant
结合使用。我已经使用variant
相当多的时间了,我非常确定所涉及的类型都没有使用过虚继承(甚至没有使用虚函数的普通继承)。w1jd8yoj2#
您可以创建模板方法来执行一次分派(或
const
版本的两次分派):Demo