1

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
  • Are you allowed to use vectors? Commented Mar 21, 2010 at 6:13

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but I cannot solve my problem. I want to A have a function that sorts arrays of type A and all subclasses of A. What is the right way to do it?
@ritmbo: is this something similar to what you want to do: codepad.org/DlErsYLj
@ritmbo: it sounds like this is a homework problem, if you can't use std::vector or std::sort. Is that correct?
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 Comments

Also, although C++ doesn't (yet) allow you to explicitly limit T to subtypes of A, when you pass T* actual parameters to a compare function that accepts A* formal parameters, the compiler will indeed enforce that T is derived (publicly) from A.
@BenVoigt: you could use an implicit cast inside the function without calling another function... like: Base* elem = array[i]; which wont compile if array is not derived from Base
@smerlin: Yes, the comparison logic could be right inside the sort function. But the inline keyword is so effective, and you get so much extra reusability from separating the sort logic from the ordering, that using a compare function is a good habit and definitely to be encouraged when teaching programming.
1

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!

1 Comment

My problem is that the f, only swap things of the array. So if I use const, then i cant do what I want to do.
0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.