'C++ creat anonymous object in the array

New to C++. Here is my main function code:

// AntsAndDoodlebug.cpp : This file contains the 'main' 
// function. Program execution begins and ends there.

#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>

using namespace std;
class Garden;
class Organism;
class Ant;
class Doodlebug;

const int Gardensize = 20;//Garden size 
const int initialants = 100;
const int antType = 1;//
const char antchar = 'O';//enter image description here

class Garden {
    friend class Organism;
    friend class Ant;
    friend class Doodlebug;

public:
    Garden();
    ~Garden();
    Organism* checkType(int x, int y);
    void Simulate1step();
    void Display();

protected:
    Organism* grid[Gardensize][Gardensize];
};

class Organism {
    friend class Garden;

public:
    virtual int getType() = 0; 
    virtual void breed() {};
    // virtual bool starve() {};
    virtual void move() = 0;
    int x = -1;              
    int y = -1;

protected:
    Garden *garden;
    bool moved = false;             
    int breedtoken = 0;     
};

Garden::Garden() {
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            grid[i][j] = NULL;
        }
    }
}

Garden::~Garden() {
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] != NULL) {
                grid[i][j] = NULL;
            }
        }
    }
}

Organism* Garden::checkType(int x, int y) {
    if (x < Gardensize && y < Gardensize) {
        return grid[x][y];
    }

    return NULL;
}

void Garden::Display() {
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] == NULL) {
                cout << ".";
            }
            else if (grid[i][j]->getType() == antType) {
                cout << antchar;
            }
            // else if (grid[i][j]->gettype() == doodletype) {
            //     cout << bugchar;
            // }
        }

        cout << endl;
    }
}

void Garden::Simulate1step() {   
    for (int i = 0; i < Gardensize; i++) { // set all organism moved token to false
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] != NULL) {
                grid[i][j]->moved = false;               
            }      
        }
    }

    for (int i = 0; i < Gardensize; i++) {   //
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] != NULL && grid[i][j]->getType() == antType) {
                cout << "in Simulation function i=" << i << " j= " << j << endl;
                grid[i][j]->move();
                // grid[i][j]->moved = true;
                // cout << "simulationstep" << endl;                
            }
        }
    }
}

class Ant : public Organism {
public:
    friend class Garden;
    Ant() {}; 
    Ant(int x, int y, Garden* garden) {
        this->x = x;
        this->y = y;
        this->g = garden;
        g->grid[x][y] = this; 
    }

    ~Ant() {};
   
    virtual int getType() { 
        return antType;
    }
    virtual void move();
    virtual void breed() {};
    virtual bool starve() { return false; };

protected:
   Garden *g;

};

void Ant::move() {
    cout << "in the move function x=" << x << "y=" << y << endl;
    int dir = rand() % 4;// randomly select a direction
    switch (dir) {
    case 0: // 0-move upwards
        if (this->x > 0 && g->grid[x - 1][y] == NULL) {
            g->grid[x - 1][y] = this;
            this-> x = x-1;   //
            g->grid[x+1][y] = NULL;     
        }
        
        break;

    case 1: // -move downwards
        if (this->x < Gardensize - 1 && g->grid[x + 1][y] == NULL) {  
            g->grid[x + 1][y] = this;
            this->x = x + 1;
            g->grid[x-1][y] = NULL;
        }
        
        break;

    case 2: // 2- move leftwards
        if (this->y > 0 && g->grid[x][y - 1] == NULL) {
            g->grid[x][y - 1] = this;
            this->y = y - 1;
            g->grid[x][y+1] = NULL;  
        }
        
        break;

    case 3: // 3-move rightwards
        if (this->y < Gardensize - 1 && g->grid[x][y + 1] == NULL) {
            g->grid[x][y + 1] = this;
            this->y = y + 1;
            g->grid[x][y - 1] = NULL;
        }
        
        break;
    }
}

int main()
{
    srand(time(NULL));
    string s;
    Garden garden;
    int antCount = 0;  // Ant counter
 
    Ant antarray[initialants]; //initialatns  = 100;

    while (antCount < initialants) {
        int x = rand() % Gardensize;
        int y = rand() % Gardensize;
        if (garden.checkType(x,y) == NULL) {
            antarray[antCount] =  Ant(x, y, &garden); //using array to creat 100 ants
            antCount++;
        }
    }

    // run program
    while (true) {
        garden.Display();
        garden.Simulate1step();
        cout << endl << "Press enter for next step" << endl;
        getline(cin, s);
    }
}

I am trying to create 100 Ants in the 2D array, and by calling Simulation1step and move functions. I want each Ant to move one step in a round. However, my code lets an Ant move 100 steps in one round.

I debug for a whole day, here are my questions:

  1. I am using an array to create Ants in a for loop, antarray[antCount] = Ant(x, y, &garden); My friend told me I should not initialize the object in a for loop's scope since the object will deconstruct when the loops are done. This is how I understand it, every time the loop is completed, the objects I created will be destructed (the memory will also be reclaimed), which means that there is no object in this array. But in the Simulation1step function, I used a cout operation to prove that I called the move function of an Ant in the array successfully. When the for loop is done, shouldn't all the objects in the array be deconstructed since it is out of the for loop's scope? Then why can I still call a function of one of the objects in the array?

  2. All of the objects in the array are anonymous objects. Is it why there is only one Ant move 100 times in one round? Again, the anonymous object will deconstruct immediately, then why in the Simulate1step function:

    for (int i = 0; i < Gardensize; i++) {   //
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] != NULL && grid[i][j]->getType() == antType) {
                cout << "In Simulationfunction i=" << i << " j= " << j << endl;
                grid[i][j]->move();
                //grid[i][j]->moved = true;
                //cout << "simulationstep" << endl;
    
            }
        }
    }
    

    I can call the move function even if the object in the grid[][] is deconstructed? And why the index of the grid[][] is changing but the move function only works on one Ant, as the picture shows?

  3. What does a destructor do? If I write an empty destructor, does it mean that this destructor does nothing? Can I still access elements that have been destructed? What is the difference between a destructor and delete?

image

c++


Solution 1:[1]

This is how I understand it, every time the loop is completed, the objects I created will be destructed

Nonsense, you're copying those objects into that antarray array. Only when that array goes out of scope your objects will be destroyed.

All the objects in the array are anonymous objects

More nonsense, only this time I can't even guess what you're trying to say.

Is it why there is only one ant move 100 times in one round?

That is not the case. You'd see that if you'd debug your program, however relying on the data displayed actually highlights a major problem with your code: it is fundamentally and absolutely broken beyond repair.

You see, for some reason you decided that your hands have x and y coordinates (Ant::x and Ant::y), while still having independent positions in Garden::grid, another set of x and y coordinates, and then you show both sets in your functions. Perhaps that's what's confusing you about that statement? Who knows.

the anonymous object will deconstruct immediately

What is it with you and anonymous objects? There's no deconstructing happening until main ends.

What is the difference between destructor and delete?

delete is an operator that invokes the destructor, then releases claimed memory back to ..something. By default, it releases memory back to the OS.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Blindy