将三个不同类的对象存储在一个数组中
Store objects of three different classes in an array
这是一个面试问题:我们如何存储三个完全独立的不同类的对象呢。
我的回答是:创建一个存储所有空指针的数组。类似:
void *array[];
并存储所有对象的指针。数组元素可以是多个。但是对于检索元素,我说过我们可以使用动态强制转换或静态强制转换!我认为这是错误的答案。我认为dynamic cast
和static cast
应该在依赖的类之间使用。如果我错了,请纠正我。
如果动态强制转换和静态强制转换不起作用。也许我们可以使用reinterpret cast
。
但这是完成这项任务的正确方法吗?
为什么要让它变得如此复杂?
struct T {
T1 obj1;
T2 obj2;
T3 obj3;
};
如果你的意思是你有一个对象数组,每个元素都可以是三种不同的、不相关的类型中的任何一种,那么这就是一个愚蠢的面试问题,因为这是一件愚蠢的事情
(是的,如果由于工作机会有限和迫切需要消费食物而被迫采用这种方法,你会考虑reinterpret_cast
。)
您可以使用boost::variant<myfoo, anotherfoo, somefoo> v
放入vector<v>
,然后可以在向量中为每个项目存储一个类,但它可以存储所有三种类型的变量。
你可以在这里找到更多关于boost::variant的信息
void*
中的dynamic_cast
是不允许的,您需要一个多态指针(即指向包含virtual
方法的类的指针)。
不能使用其他强制转换,因为强制转换的目标类型未知。一旦将类型化指针投射到void*
,类型信息将永远丢失。只要给定一个指针,就没有机会返回该类型信息。你需要以某种形式记住某个地方的类型。enum { one, two, three }
和void*
一起怎么样?
唯一"正确"的方法是使用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;
}
}
};
等等基本框架。)