How to make an array with polymorphism in C ++?

class Base1 { private: int testInput; public: Base1(); virtual int GetRow(void) = 0; }; Base1::Base1() { testInput = 0; } class table : public Base1 { private: int row; public: table(); virtual int GetRow(void); }; table::table() { //Contructor row = 5; } int table::GetRow() { return row; } int main () { Base1* pBase = new table[3]; pBase[0].GetRow(); pBase[1].GetRow(); //when i get to this line, the compiler keep saying access // violation. pBase[2].GetRow(); return 0; } 

I am trying to create an array of 3 table classes. Requirement: I have to use a Base object for this.

 Base1 * pBase = new table[3]; 

good looking. But when I tried to access each table, the compiler said it was an access violation. I do not know what happened with this code. I am using Visual Studio 2010, though.

+6
source share
4 answers

In C ++, polymorphism and arrays do not mix.

Since in general the size of the derived class is different from the size of the base class, polymorphism and pointer arithmetic do not play well together. Because array access includes pointer arithmetic, expressions such as pBase[1] do not work as pBase[1] .

One possibility is to have an array of pointers to your objects, perhaps even smart pointers, to simplify memory management. But don't forget to define a virtual destructor in Base1 .

+13
source

You get an error because the array is statically printed on Base1 . This means that this line:

 pBase[1].GetRow(); 

adds the size of Base1 in bytes to pBase and interprets this as the beginning of another Base1 object, but it actually points somewhere in the middle of the first table instance.

If you need an array of polymorphic instances, you should store them in an array (or preferably in std::vector ) using pointers (or, preferably, some forms of smart pointers).

+6
source

Agnew's reaction was in place. Let me explain a little more. Increasing the code, I print the size of the Base1 and table object, as well as the addresses of the three table objects created by the new operator:

 A Base1 object is 8 bytes A table object is 12 bytes A table object is being constructed at 0x002977C0 A table object is being constructed at 0x002977CC A table object is being constructed at 0x002977D8 

As you can see, these objects are located at a distance of 12 bytes from each other in memory.

Now type in the addresses that pBase [0], pBase [1] and pBase [2] give:

 pBase[0] is at 0x002977C0 pBase[1] is at 0x002977C8 pBase[2] is at 0x002977D0 

Now let's see what happens: the pointers that we return are located at a distance of 8 bytes. This is due to the fact that pointer arithmetic is performed on a pointer whose type is Base1 , and since Base1 is 8 bytes long, which the compiler does, translate pBase[n] into pBase + (n * sizeof(Base1)) .

Now you can understand exactly why the first GetRow() works and why you crashed into the second.

+4
source

You need to create (with new ) all these array elements, do it like this:

 for(int i = 0; i < 3; ++i) pBase[i] = new table(); 
+3
source

All Articles