不明白你的意思。听起来您按值存储对象,并且您有一个Base
. 那是行不通的,因为一旦您分配了 Derived,该对象就会被转换为 Base,并且对象的 Derived 部分会被切掉。但我认为你想要一个指向基础的指针数组:
Base * bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i] = new Derived1;
else if(r == 1)
bases[i] = new Derived2;
// ...
}
如果你曾经使用过指针,你就会知道管理它们是一件很痛苦的事情,尤其是传递而不丢失它们,因为你需要对它们调用 delete 以释放内存并调用对象的析构函数。您可以使用 shared_ptr,它会为您管理:
shared_ptr<Base> bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i].reset(new Derived1);
else if(r == 1)
bases[i].reset(new Derived2);
// ...
}
现在,您可以传递bases[x]
给另一个 shared_ptr,它会注意到您有多个引用 - 如果对对象的最后一个引用超出范围,它将自动调用 delete。理想情况下,您还可以用 std::vector 替换原始数组:
std::vector< shared_ptr<Base> > bases;
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases.push_back(shared_ptr<Base>(new Derived1));
else if(r == 1)
bases.push_back(shared_ptr<Base>(new Derived2));
// ...
}
然后您可以传递向量,并且不会丢失它的大小,并且您可以根据需要动态添加项目。使用 获取向量的大小bases.size()
。shared_ptr
在这里阅读。
从基类到派生类的转换只应在绝对必要时进行。通常,您想使用一种称为 的技术polymorphism
,这意味着您在基指针上调用一个函数,但它实际上会调用一个在派生类中定义的函数,具有相同的签名(名称和参数是相同的类型)并且据说给override
它。阅读维基百科上关于它的文章。如果你真的需要强制转换,你可以对原始指针这样做:
Derived1 * d = &dynamic_cast<Derived1&>(*bases[x]);
使用 dynamic_cast 可确保当您转换为错误的类型(即,您转换的类型不是创建并分配给基指针的类型)时,您会得到运算符抛出的异常。对于 shared_ptr 情况,也有一些方法:
shared_ptr<Derived1> d = dynamic_pointer_cast<Derived1>(bases[x]);
if(d) {
// conversion successful, it pointed to a derived. d and bases[x] point still
// to the same object, thus share it.
}