Casting array of pointers to objects

余生长醉 提交于 2019-12-24 08:38:05

问题


If B is subclass of A.

And I have in main():

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

So I have an array of pointers to objects B.

Then I have a function:

void f(A** foo);

If in main, I do: f(b); I get a warning, but obviously if I do: f((A**)b);, I don't.

The (A**) its a bit nasty. I was wondering if there's a more elegant way in C++ that at least do type checking as dynamic_cast.

I want foo to sort (only using swaps) arrays of objects of type A or subclass.. so make a generic sorting algorithm. I hope now you understand better my problem.


回答1:


A** and B** are two totally different types. Just because there is an implicit conversion from B* to A* does not mean that the same conversion exists from B** to A** See this FAQ Converting Derived* → Base* works OK; why doesn't Derived** → Base** work? for more details.




回答2:


There's a reason you get a warning or error if you try to implicitly cast a B** to a A**: it's not safe to do so.

Referring to the array as a A** allows you to put pointers to A objects inside. For an array of B* this is wrong and therefor the cast is unsafe.

Maybe f would better be a template function:

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



回答3:


The case is incorrect. Suppose the function is (perfectly legitimate):

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

now if you passed a B** instead, the first pointer (which the compiler is certain is a B*) has suddenly become an A* -- terrible type-violation, hard-crash likely soon.

A** -- no const in sight, please notice! -- means a mutable pointer to mutable pointers to A, which is why setting one of those pointers to a new pointer to A is perfectly OK. But you can't do that if you actually have a B** -- those pointers must always be to B (or subclass thereof), not to A, a superclass of B.

Yep, it's covariance vs contra-variance all over again -- under mutability (no const in sight), it's really a minefield. Why not stick in all the const you can possibly afford? This will also indicate which casts make sense under which circumstances!




回答4:


If B is a subclass of A then you can still sort a list of pointers to objects of type B even if the type of the array is "array of pointers to A".

E.g.

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

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

// ...

ptrToBs[9] = &b10;

f(ptrToBs);

However, what you say you want is a generic algorithm to swap objects, not pointers based on the value of the pointed-to objects. In this case, you are better off having a function template.

template< class T >
void f(T* t)
{
    // ...
}

This way you can sort an array of A or and array of B without having to have an array of pointer to exactly the right type; you can just sort an array of A or B objects or anything else provided that the type of objects that you are sort support the operations that you are using in your sort algorithm.

Typically you would want to pass the size of the array or a pointer to the end of the array so that the algorithm doesn't have to assume how big the array is.

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

or

template< class T > void f(T* first, T* last);


来源:https://stackoverflow.com/questions/2486056/casting-array-of-pointers-to-objects

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!