转换对象的指针数组

时间:2010-03-21 05:26:18

标签: c++ casting

如果BA的子类。

我在main()

B** b = new B*[10];
... // some algorithm that does b[i] = new B(..);

所以我有一个指向对象B的指针数组。

然后我有一个功能:

void f(A** foo);

如果在主要方面,我会这样做:f(b);我会收到警告,但很明显,如果我这样做:f((A**)b);,我就不会。

(A**)它有点讨厌。我想知道在C ++中是否有更优雅的方式,至少将类型检查作为dynamic_cast

我希望foo对A类或子类的对象数组进行排序(仅使用交换)。所以制作一个通用的排序算法。我希望你现在能更好地理解我的问题。

4 个答案:

答案 0 :(得分:2)

A**B**是两种完全不同的类型。仅仅因为存在从B*A*的隐式转换并不意味着从B**A**存在相同的转换。有关详细信息,请参阅此常见问题解答Converting Derived* → Base* works OK; why doesn't Derived** → Base** work?

答案 1 :(得分:2)

如果您尝试隐式地将B**强制转换为A**,则会出现警告或错误:这样做是不安全的。

将数组作为A**引用,允许您在其中放置指向A个对象的指针。对于B*的数组,这是错误的,因此演员表是不安全的。

也许f最好是模板功能:

template<typename T>
void f(T **array) {
   ...
}

答案 2 :(得分:1)

案件不正确。假设该函数是(完全合法的):

void f(A** foo)
{
  foo[0] = new A();
}

现在如果你传递B** instead,第一个指针(编译器肯定是B*)突然变成A* - 可怕的类型违规,硬崩溃可能很快。

A** - 没有const在眼前,请注意! - 表示指向 mutable 指针的 mutable 指针,这就是为什么将其中一个指针设置为A的新指针是完全正常的原因。但是,如果你确实有一个B** - 那些指针必须始终是B(或子类),那么你不能这样做 AB超类

是的,它的协方差和反方差一再重复 - 在可变性(看不到const)的情况下,它真的是一个雷区。为什么不坚持你可能负担的所有const?这也将表明哪些演员阵容在哪种情况下有意义!

答案 3 :(得分:0)

如果BA的子类,那么你仍然可以对类型为B的对象的指针列表进行排序,即使数组的类型是“指针数组{ {1}}”。

E.g。

A

但是,您想要的是一种交换对象的通用算法,而不是基于指向对象值的指针。在这种情况下,您最好使用功能模板。

A** ptrToBs = new A*[10];

ptrToBs[0] = &b01; // ... or new B
ptrToBs[1] = &b02;

// ...

ptrToBs[9] = &b10;

f(ptrToBs);

通过这种方式,您可以对template< class T > void f(T* t) { // ... } A数组进行排序,而无需使用指向正确类型的指针数组;您可以对BA个对象或其他任何对象进行排序,前提是您排序的对象类型支持您在排序算法中使用的操作。

通常,您需要传递数组的大小或指向数组末尾的指针,以便算法不必假设数组有多大。

B

template< class T > void f(T* arr, std::size_t size);