Initializing static 2D array member?

I want my class to have a static member variable that is a 2D array, But I don't know where to initialize it.

The code below is meant to initialize the static 2D array member 'grid' of class Organism.
1
2
3
4
  8 //Initializing static member 'grid'------
  9 for (int i = 0; i < FIELD_SIZE; i++)
 10     for (int j = 0; j < FIELD_SIZE; j++)
 11         char Organism::grid[i][j] = '-';


However the compiler does not allow me to put this in the file scope like static members are usually defined.
Last edited on
Well, at the beginning of main. For cleanliness, you should write a static init() function which would do this. If you want to avoid that, you could also wrap the grid in a class and initialize in its constructor.
Initializing in main.cpp will not work because Organism.cpp uses 'grid'. Since main.cpp depends on organism.cpp, organism.cpp is compiled first and is referencing the undefined grid..
Why does compilation order matter...?
I'm sorry, compilation order doesn't matter.. I was just initializing the array incorrectly. Here is the init function i created..

1
2
3
4
5
6
7
8
9
 21 char Organism::grid[FIELD_SIZE][FIELD_SIZE];
 22 void Organism::init_grid()
 23 {
 24 //Initializing static member 'grid'------
 25     for (int i = 0; i < FIELD_SIZE; i++)
 26         for (int j = 0; j < FIELD_SIZE; j++)
 27             grid[i][j] = '-';
 28 //--------------------------
 29 }


This seems to work correctly when I call Organism::init_grid() in the beginning of main(). One more question though - why do static member variables need to be declared twice (once in class header and again outside of the class)?

Last edited on
They are not declared twice, only once. They are declared inside the class and defined outside in a cpp file. It is for the same reason as functions - a function must always have a definition, so if you only provide a declaration, and no definition...well, it can't figure out what to do. Another note is that in a declaration, you can't do static int MyInt = someFunc();; this is what definitions are for.
OK thanks a lot. It seems like I'm beginning to have another problem now though. I am getting multiple definition errors of Organism::grid inside the constructors of the classes derived from Organism.

critters.o: In function `Ant':
/home/jack/Problem_Solving_With_C++_Projects/Projects/15-11/critters.cpp:8: multiple definition of `Organism::grid'
organism.o:/home/jack/Problem_Solving_With_C++_Projects/Projects/15-11/organism.cpp:7: first defined here
main.o: In function `main':
/home/jack/Problem_Solving_With_C++_Projects/Projects/15-11/main.cpp:10: multiple definition of `Organism::grid'
organism.o:/home/jack/Problem_Solving_With_C++_Projects/Projects/15-11/organism.cpp:7: first defined here
collect2: ld returned 1 exit status

Ant is a class derived from Organism with its implementation in critters.cpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef ORGANISM_H
#define ORGANISM_H
#include <vector>
using namespace std;
const int FIELD_SIZE = 20;

struct Tuple
{
	Tuple();
	Tuple(int the_x, int the_y);
	
	int x, y;
	bool operator ==(const Tuple &rhs);
};

class Organism
{
public:
	Organism();
	Organism(int x_coord, int y_coord);	

	int get_x_coord() {return coords.x;}
	int get_y_coord() {return coords.y;}
	char get_id() {return id;}

	void die() {alive = false;}	
	bool is_alive();
	void update_alive();	
	
	void move();	
	vector<Tuple> neighbors();	

	static char grid[FIELD_SIZE][FIELD_SIZE];
	static void init_grid();
protected:
	char id;
	bool alive; 
	Tuple coords; 
};

char Organism::grid[FIELD_SIZE][FIELD_SIZE];

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <iostream>
#include <vector>
#include <cstdlib>
#include "organism.h"
using namespace std;

Tuple::Tuple() : x(0), y(0)
{
	//leave blank
}

Tuple::Tuple(int the_x, int the_y) : x(the_x), y(the_y)
{
	//leave blank
}

bool Tuple::operator ==(const Tuple &rhs)
{
	return ((x == rhs.x) && (y == rhs.y));
}

void Organism::init_grid()
{
//Initializing static member 'grid'
	for (int i = 0; i < FIELD_SIZE; i++)
		for (int j = 0; j < FIELD_SIZE; j++)
			grid[i][j] = '-';	
//--------------------------
}

Organism::Organism()
{
	id = 'z';
	alive = true;

	coords.x = rand() % 20;
	coords.y = rand() % 20;

	grid[coords.y][coords.x] = id;	
}

Organism::Organism(int x_coord, int y_coord)
{
	id = 'z';
	alive = true;
	
	coords.x = x_coord;
	coords.y = y_coord;

	grid[coords.y][coords.x] = id;	
}	
void Organism::move()
{			
	vector<Tuple> the_neighbors = neighbors(); //returns neighboring coordinates

	vector<Tuple> valid_choices;
	Tuple valid_choice;
	bool valid; 
	for (unsigned int i = 0; i < the_neighbors.size(); i++)
	{
		valid = true; 
		if ((grid[the_neighbors[i].y][the_neighbors[i].x] != '-')
				&& (the_neighbors[i].y != coords.y || the_neighbors[i].x != coords.x))
			valid = false;
		if (valid)
		{
			valid_choice.y = the_neighbors[i].y;
			valid_choice.x = the_neighbors[i].x;
			valid_choices.push_back(valid_choice);
		}
	}
	
	if (valid_choices.size() > 0)
	{
		grid[coords.y][coords.x] = '-'; // remove previous location;
			
		int randomizer = rand() % valid_choices.size(); //randomizes choice of next valid move.
		coords.y = valid_choices[randomizer].y;
		coords.x = valid_choices[randomizer].x;

		grid[coords.y][coords.x] = id;
	}
}

vector<Tuple> Organism::neighbors()
{
	vector<Tuple> neighbors;

	neighbors.push_back(Tuple(coords.x, coords.y-1));
	neighbors.push_back(Tuple(coords.x-1, coords.y));
	neighbors.push_back(Tuple(coords.x+1, coords.y));
	neighbors.push_back(Tuple(coords.x, coords.y+1));
	neighbors.push_back(Tuple(coords.x, coords.y));

	for (unsigned int i = 0; i < neighbors.size(); i++) //gets rid of out-of-bounds neighbors
		if ((neighbors[i].x > 19) || (neighbors[i].y > 19) || (neighbors[i].x < 0) || (neighbors[i].y < 0))
		{
			neighbors.erase(neighbors.begin() + i);
			i--;
		}

	return neighbors;
}

bool Organism::is_alive()
{
	return alive;
}

void Organism::update_alive()
{
	if (grid[coords.y][coords.x] != id)
		alive = false;
}


And in main() I call Organism::init_grid()

Is there anything wrong with the way I'm going about this that would cause multiple definition errors?
Last edited on
Yes - you're defining Organism::grid in the header file, which is included in multiple cpp files. You can't define the same thing more than once, not even in separate cpp files. You should define Organism::grid in a cpp file, not a header, the same way you define the Organism:: functions.
Ah I see, Thanks very much.
Why is it that I cannot define grid in organism.cpp without getting a multiple definition error? It seems to only work when I define it in main.cpp
Topic archived. No new replies allowed.