这是一个面试问题: 我们怎样才能存储3个不同类的对象,这些类完全相互独立。
我的回答是: 创建一个存储所有void指针的数组。 喜欢:
void *array[];
并存储所有对象的指针。数组元素可以很多。
但是为了检索元素,我说我们可以使用动态模型或静态模型!
我认为这是错误的答案。我认为dynamic cast
和static cast
应该在依赖的类中使用。
如果我错了,请纠正我。
如果动态强制转换和静态强制转换不起作用。我们可以使用reinterpret cast
。
但这是完成此任务的正确方法吗?
答案 0 :(得分:5)
你为什么要这么复杂?
struct T {
T1 obj1;
T2 obj2;
T3 obj3;
};
如果你的意思是你有一个对象数组,并且每个元素可以是三种不同的,不相关的类型中的任何一种,那么这是一个愚蠢的面试问题,因为这是一个愚蠢的事情。
(是的,如果被迫通过有限的工作机会和消费食物的迫切需要而被迫采用这种方法,你会考虑reinterpret_cast
。)
答案 1 :(得分:3)
您可以使用boost::variant<myfoo, anotherfoo, somefoo> v
放入vector<v>
,然后您可以在向量中为每个项目存储一个类,但是它可以存储所有三种类型的变量。
您可以在boost :: variant here
上找到更多信息答案 2 :(得分:1)
dynamic_cast
的 void*
是不允许的,你需要一个多态指针(也就是指向一个带有virtual
方法的类的指针。)
您不能使用其他强制转型,因为未知投射的目标类型。将类型指针强制转换为void*
后,类型信息将永远丢失。仅给出指针,您就没有机会获得该类型信息。你需要以某种形式记住某个地方的类型。 enum { one, two, three }
旁边的void*
怎么样?
答案 3 :(得分:1)
唯一“正确”的方法是使用类似的东西
boost::variant
。如果你不能使用提升,那么你必须更少
做同样的事情:实现一个接受所有的歧视联盟
所需的类型。这并不像看起来那么难:对于POD类型,
你可以使用普通的union
来获取数据;对于非POD类型,你
将unsigned char x[sizeof(T)]
添加到联合,并使用placement new和
根据需要显式删除它。并添加必要的内容
联盟以确保对齐。因此,对于用户类型MyClass和double,
一个可能有类似的东西:
class MyVariant
{
public:
enum Type { t_double, t_MyClass };
private:
Type m_type;
union
{
double m_double;
unsigned char m_MyClass[sizeof(MyClass)];
MaxAlignFor<MyClass> m_dummyForAlignment_MyClass;
};
public:
MyVariant( double d )
: m_type( t_double )
{
m_double = d;
}
MyVariant( MyClass const& c )
: m_type( t_MyClass )
{
new (m_MyClass) MyClass( c );
}
~MyVariant()
{
switch ( m_type )
{
case t_double:
break;
case t_MyClass:
reinterpret_cast<MyClass*>( m_MyClass )->~MyClass();
break;
}
}
};
等等。 (显然有很多涉及,但这应该给 基本框架。)