2

I'm declaring a 2-D dynamic array of Base class. Some of these dynamic objects are being declared as objects of Derived class. The constructor of the Derived class is being called on, but the object of Derived class is not calling on the correct virtual function

Organism is Base class Ant is Derived class

Organism.cpp

Organism::Organism(){//default constructor
    occupy = false;
    mark = '_';
}
Organism::Organism(int){//constructor called on by the Ant constructor
    occupy = true;
}
char Organism::getMark(){//Used to make sure the Ant constructor is properly called
    return mark;
}
virtual void yell(){//virtual function
        cout << "organism" << endl;
    }

Ants.cpp

Ant::Ant() : Organism(){}//not really used
Ant::Ant(int) : Organism(5){//initialize the Ant object
    setMark('O');//mark
    antsNum++;
}
void yell(){//override the virtual function 
        cout << "ant" << endl; 
    }

main.cpp

Organism **grid = new Organism*[20];
char c;
    ifstream input("data.txt");//file contains data

    for (int i = 0; i < 20; i++){

        grid[i] = new Organism[20];//initialize the 2d array

        for (int j = 0; j < 20; j++){
            input >> c;//the file has *, X, O as marks

            if (c == '*'){
                grid[i][j] = Organism();//call on the default constructor to mark it as _
            }
            else if (c == 'X'){
                grid[i][j] = Doodle(5);
            }
            else if (c == 'O'){
                grid[i][j] = Ant(5);
            }
        }
    }
//out of the loop

cout << grid[1][0].getMark() << endl;//outputs 'O', meaning it called on the ant constructor
    grid[1][0].yell();//outputs organism, it is not calling on the Ant definition of the function yell()

I do understand that all the array is of type Organism, not of type Ant, how do I change that?

Thy Gamosh
  • 77
  • 1
  • 7
  • 3
    Have a matrix of *pointers* to the base-type? And is there a reason you're not using [`std::vector`](http://en.cppreference.com/w/cpp/container/vector)? – Some programmer dude Apr 17 '15 at 12:23
  • I really don't like vectors, and then I have to use other functions that will will have to move, destroy and breed other objects. Will try vectors later I guess. – Thy Gamosh Apr 17 '15 at 12:35
  • Using the [C++ standard library](http://en.cppreference.com/w/cpp), including its [containers](http://en.cppreference.com/w/cpp/container) and [algorithms](http://en.cppreference.com/w/cpp/algorithm) will make your life as a C++ programmer so much easier and pleasant in the long run. – Some programmer dude Apr 17 '15 at 12:40

2 Answers2

1

You need to declare your array as pointer to pointer to pointer:

Organism ***grid = new Organism**[20];

The matrix now holds pointers to Organism. The way you did it you are initializing an Organism with Doodle instead of having an Organism be a Doodle.

You should have:

grid[i][j] = new Doodle(5);

Right now what is happening is Organisms copy constructor is being called so you are actually storing Organisms instead of pointers to derived types.

An even better way of doing it is to use boost::matrix:

boost::matrix<Organism *> m(20, 20);
Benjy Kessler
  • 7,356
  • 6
  • 41
  • 69
1

You have object slicing here.

There are twenty Organisms created:

grid[i] = new Organism[20];//initialize the 2d array

And then, you try to copy a temporary Ant into the Organism at [i][j]:

grid[i][j] = Ant(5);

but this doesn't work.

Remove the first line (initialize..), and replace the second line with

grid[i][j] = new Ant(5);

and likewise for the Organism and Doodle.

Community
  • 1
  • 1
alain
  • 11,939
  • 2
  • 31
  • 51