Jump to content
  • Advertisement
Sign in to follow this  
fpsgamer

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

This topic is 3659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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???

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!