[C++] Wait wut? What is wrong with this code?

Started by
22 comments, last by Decrius 15 years, 10 months ago
I came across this link here on the forums. I don't understand the point that is being made in the first item titled: "Arrays are not Polymorphic". First of all I don't see anything wrong with the code they posted. Secondly what could "Arrays are not Polymorphic" possibly mean???
Advertisement
I'm not sure that'd produce a runtime exception, but I suspect it's wrong. Basically, polymorphism only works (in C++) when you're using pointers. Arrays don't quite deal with pointers. (or rather they do, but the also deal with the size of the objects, which will vary from base to derived):

Base[3] makes : [---][---][---]
Derived[3] is : [----][----][----]

using derived[3] where the code expects base[3] causes the pointer offsets to be messed up. Delete will nuke the wrong number of bytes. And in general "bad things" occur.

Personally, I consider arrays a code smell, and avoid them in nearly all cases.
Quote:Original post by fpsgamer
what could "Arrays are not Polymorphic" possibly mean???

An array of Apples is not an array of Fruits, because an array of Fruits allows insertion of an Orange, whereas an array of Apples must forbid that.
You CAN make an array with _pointers_ to base and derived classes, since pointers are always the same length in memory ;).

class Base{};class Derived: public Base{};Base *array[2];array[0] = new Base;array[1] = new Derived;delete array[1];delete array[0];


I believe this is perfectly alright.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Apple* is a subtype of Fruit*.
Apple** is NOT a subtype of Fruit**.

Consider the following code:
#include <iostream>#include <string>using namespace std;struct Fruit{    virtual string description()    {        return "fruit";    }};struct Apple : public Fruit{    virtual string description()    {        return "apple";    }};struct Orange : public Fruit{    virtual string description()    {        return "orange";    }};int main(){    Apple** apples = new Apple*[2];    apples[0] = new Apple();    Fruit** fruits = apples; // compiler error: invalid conversion from Apple** to Fruit**    fruits[1] = new Orange();}

If the third line of main was legal, we could insert an Orange into an array of Apples.
Quote:Original post by DevFred
Quote:Original post by Decrius
I believe this is perfectly alright.

No, it's not. See my reasoning about Apples and Oranges.


Yes it is, you can have an array of Base pointers in the same way you can have a std::vector of Base pointers.
Quote:Original post by rip-off
you can have an array of Base pointers in the same way you can have a std::vector of Base pointers.

Of course, pointers are polymorphic. But that's not the question. The arrays themselves are not polymorphic, and so aren't vectors. You can't do this:
std::vector<Derived*> d;std::vector<Base*>& b = d; // illegal, since vectors aren't polymorphic


Oh, I didn't really read decrius' post, I was still set on the op's question, sorry.
Thanks for the replies, it now makes perfect sense :)
Quote:Original post by Decrius
since pointers are always the same length in memory ;).

Incorrect. In C++, the only two pointer types that are guaranteed to have the same size and alignment are (possibly cv-qualified) void pointers and (possibly cv-qualified) pointers to char. In particular, pointers to members are often up to four times the size of a pointer to void.
Quote:Original post by SiCrane
Quote:Original post by Decrius
since pointers are always the same length in memory ;).

Incorrect. In C++, the only two pointer types that are guaranteed to have the same size and alignment are (possibly cv-qualified) void pointers and (possibly cv-qualified) pointers to char. In particular, pointers to members are often up to four times the size of a pointer to void.


If only void* and char* are defined to have the same size and alignment, how can this be reasonably portable:
class Foo{...};Foo f;void* bar = &f // void* and Foo* don't necessarily have the same size!

This topic is closed to new replies.

Advertisement