Skip to main content
gamedev.net
🔒 Locked

template array class problem.......

Started by BlackWind Jan 2, 2007 at 7:40 PM 9 replies 1.4k views
Original Post
BlackWind
BlackWind
hi, based on the book "data structures for game programmers", i have an array manipulation class with templates. this is an example of how it can initializes an int array: ArrayClass aIntegers(4); aIntegers[0] = 3; aIntegers[1] = 8; aIntegers[2] = 4; aIntegers[3] = 2; it can also insert, remove, and resize. this is how the templates initializes the size:

ArrayClass( int size )
{
	//m_pArrayData = 0;
	m_pArrayData = new DataType[size];	// init the dynamic array
	m_arraySize = size;					// size of the array
}
this is the way the "[]" is overloaded to init the positions of the array:

DataType& operator[]( int index )
{
	return m_pArrayData[index];		// i.e. array[20] = 10
}
my question is: if possible, how can i do a function that overloads some operator for this type of initialization..... ArrayClass aIntegers(4); aIntegers = {1,2,3,4}; thanks a lot......
Zakwayda
Zakwayda
I would start by taking a look at this.

You should also be aware that you're basically reimplementing std::vector. I'm not sure when the book you're working from was written, but for what it's worth it's no longer a given in game development that everything must be written from scratch for 'maximum efficiency' or whatever. So if your aim is to be productive and/or make games, I'd strongly recommend using existing tools where possible. However, if you're interested in pursuing this as a learning exercise, the Boost link may still be useful as an example of how the type of initialization syntax you mention can be emulated in C++.
Zahlman
Zahlman
Quote:
Original post by BlackWind
my question is:
if possible, how can i do a function that overloads some operator for this type of initialization.....

ArrayClass aIntegers(4);
aIntegers = {1,2,3,4};

thanks a lot......


... sigh.

Assignment and initialization are different things.

When you write something like "int foo = 3;", you initialize foo as 3.

When you write something like "int foo; foo = 3;", you declare foo, and then assign 3 to foo.

These are not the same actions.

When you write "aIntegers = {1,2,3,4}", you are attempting an assignment, because this isn't the line where you declared the variable (hint: no typename is provided). There is no way to make your class support this - and arrays do not support it either.

If you really did mean initialization, then it would have to look like "ArrayClass aIntegers = {1, 2, 3, 4};", i.e. all in one statement. That way, it actually is initialization.

In order to be allowed to do this, what you need to do is make the structure a POD struct. That is, it can only (recursively) contain primitives, and no constructors or a destructor. (Thus, you couldn't initialize with this and also specify constructor parameters in parentheses - but that is true of initialization in general: you can either use "constructor style" or "assignment style", not both. Incidentally, "int foo(3);" is legal and does what you might expect.)

That is, of course, at odds with your design where you specify a size in the constructor and manage memory dynamically. To make it work, you would have to specify the size at compile time. That doesn't limit you to a specific size, though; you can use templates, with an integer as a template parameter. (Template parameters can be either type-names, or values of integral type, including booleans and enums.)

However, that wheel already exists: see boost::array.
BlackWind
BlackWind
well, thanks both for your advices
it wanted to do that for a learning exercise and because i wanted to expand the class for using 3d arrays, but std::vector can also manipulate 3d arrays..... cant it?
And i'm going to take a look to the boost library....
gdunbar
gdunbar
Quote:
Original post by BlackWind
well, thanks both for your advices
it wanted to do that for a learning exercise and because i wanted to expand the class for using 3d arrays, but std::vector can also manipulate 3d arrays..... cant it?
And i'm going to take a look to the boost library....


To my limited knowledge, std::vector only handles 1d arrays. However, rather than implementing a whole new class, you probably want to use std::vector and extend it with your 3d addressing system, rather than writing a whole new class.

As for your first point, writing your own array class as a learning exercise is a very worthwhile thing to do.

Geoff
discman1028
discman1028
Quote:
Original post by BlackWind
well, thanks both for your advices
it wanted to do that for a learning exercise and because i wanted to expand the class for using 3d arrays, but std::vector can also manipulate 3d arrays..... cant it?
And i'm going to take a look to the boost library....


I tried to use boost's arrays and views for 3D arrays, it might be confusing for beginners. Here's an idea of how to wrap a 1D array (std::vector) to make a 2D array (note that a 2D array (e.g. int arr[3][3];) is just a 1D array behind the scenes):

class Vector2D{public:	// Constructor.	Vector2D() {}	// Constructor.	Vector2D( int numRows, int numCols )		: m_numRows(numRows), m_numCols(numCols) { m_data.resize( m_numRows*m_numCols ); }	// Destructor.	~Vector2D() {}	// Accessor.	int& operator()( int row, int col )	{		return m_data[ m_numCols*row + col ];	}private:	// Members.	int m_numRows;	int m_numCols;	std::vector<int> m_data;};int main(){	Vector2D v( 2, 3 );	v( 0, 0 ) = 0;	v( 0, 1 ) = 1;	v( 0, 2 ) = 2;	v( 1, 0 ) = 3;	v( 1, 1 ) = 4;	v( 1, 2 ) = 5;	// ...	return 0;}


A few things to do from here:

1) Generalize to any type (need to learn about making a templated class, not just using one.)

2) Generalize to 3D... just a bit of math.

3) Insert, remove, resize functions (just forward requests to std::vector m_data;)

HTH

EDIT: I just noticed the AP's post above. That way works, but is less efficient, since it is not a 1D array behind the scenes -- it is an array of 1D arrays.
--== discman1028 ==--
BlackWind
BlackWind
Thanks for your answers...

Quote:
Original post by discman1028

EDIT: I just noticed the AP's post above. That way works, but is less efficient, since it is not a 1D array behind the scenes -- it is an array of 1D arrays.


and the difference is that much that its better to do my own 3d template array class using std::vector?

what would be best?
- using 3d std::vector as AP's said.
- using boost library
- do my own 3d template array class using std::vector

and why?
_goat
_goat
Quote:
Original post by BlackWind
Thanks for your answers...

Quote:
Original post by discman1028

EDIT: I just noticed the AP's post above. That way works, but is less efficient, since it is not a 1D array behind the scenes -- it is an array of 1D arrays.


and the difference is that much that its better to do my own 3d template array class using std::vector?

what would be best?
- using 3d std::vector as AP's said.
- using boost library
- do my own 3d template array class using std::vector

and why?


The difference is, if you have three vectors, then you have three times the amount of data the vectors are keeping for internal maintenance. Furthermore, you have three times the amount of access overhead (bounds checking, etc). discman's way of doing it eliminates these problems, and is also the way boost::array does it. I would go with boost::multi_array because it's already, for all intents and purposes, a "3d template array class using std::vector". In fact, it's all dimensions you require.

Boost.MultiArray Documentation
discman1028
discman1028
Quote:
Original post by _goat

The difference is, if you have three vectors, then you have three times the amount of data the vectors are keeping for internal maintenance. Furthermore, you have three times the amount of access overhead (bounds checking, etc). discman's way of doing it eliminates these problems, and is also the way boost::array does it. I would go with boost::multi_array because it's already, for all intents and purposes, a "3d template array class using std::vector". In fact, it's all dimensions you require.

Boost.MultiArray Documentation


I agree with this! The only thing I would add is, if Boost.MultiArray is hard to understand, come back to my example. ;)
--== discman1028 ==--
BlackWind
BlackWind
well, thanks for your answers!!
i'm gonna take a look on the boost library......

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.