How Would I Code This In C++?


Kramy

Active Member
Joined
Mar 15, 2008
Messages
688
Hi. Because of the lack of java support on my GP2X, I'm now attempting to learn C++.

But it isn't going so great. C++'s complicated syntax is spanking me with compiler errors. :lol: I can see why there's courses for this language. It's not something you just start typing, and it works. ;)

Anyway, I'm a noob when it comes to compiled languages. I have no idea what needs to be fixed. I figured since in C there's no garbage collector, it'd be a good idea to have a big list of all the surfaces loaded into memory, so I can keep track of them, and delete them through that object. Good concept anyway, right?

So I figured....arr[16] of pointers that points to arr[64] of pointers to surfaces. That combo allows up to 1024 surfaces, which is more than I could possibly use, while also keeping memory usage to ~(16*4 + n*64*4 + overhead) bytes.

Unfortunately, that concept maps very poorly into actual code, since my brain and fingers don't know how to get it working.

So anyways...Java:
CODE
public class imageCache
{
public int MaxChunks = 16;
public int ChunkSize = 64;
public int maxSize = MaxChunks*ChunkSize;
public int Count = 0;

public Chunk[] Chunks = new Chunk[MaxChunks];



final public boolean outOfBounds(int iNum)
{
return (iNum < 0 || iNum >= maxSize);
}



final public SDL_Surface get(int iOffset)
{
if(outOfBounds(iOffset)) return null;
int iChunk = iOffset >> 6;
int iIndex = iOffset & 63;


if(Chunks[iChunk] == null) return null;
return Chunks[iChunk].Arr[iIndex]; // May be null
}



final public int add(SDL_Surface mySurf)
{
if(Count >= maxSize) return -1;
int iChunk = Count >> 6;
int iIndex = Count & 63;


if(Chunks[iChunk] == null) Chunks[iChunk] = new Chunk(ChunkSize);
Chunks[iChunk].Arr[iIndex] = mySurf;


iIndex = Count;
Count++;
return iIndex; // Return Index/Offset
}



private class Chunk
{
public SDL_Surface Arr[];

Chunk(int iSize)
{
Arr = new SDL_Surface[iSize];
}
}
}


If anyone has the time to convert that, I'd be grateful. :D

-Kramy
 
Kramy said:
Hi. Because of the lack of java support on my GP2X, I'm now attempting to learn C++.

But it isn't going so great. C++'s complicated syntax is spanking me with compiler errors. :lol: I can see why there's courses for this language. It's not something you just start typing, and it works. ;)

Anyway, I'm a noob when it comes to compiled languages. I have no idea what needs to be fixed. I figured since in C there's no garbage collector, it'd be a good idea to have a big list of all the surfaces loaded into memory, so I can keep track of them, and delete them through that object. Good concept anyway, right?

So I figured....arr[16] of pointers that points to arr[64] of pointers to surfaces. That combo allows up to 1024 surfaces, which is more than I could possibly use, while also keeping memory usage to ~(16*4 + n*64*4 + overhead) bytes.

Unfortunately, that concept maps very poorly into actual code, since my brain and fingers don't know how to get it working.

So anyways...Java:
CODE
public class imageCache
{
public int MaxChunks = 16;
public int ChunkSize = 64;
public int maxSize = MaxChunks*ChunkSize;
public int Count = 0;

public Chunk[] Chunks = new Chunk[MaxChunks];
final public boolean outOfBounds(int iNum)
{
return (iNum < 0 || iNum >= maxSize);
}



final public SDL_Surface get(int iOffset)
{
if(outOfBounds(iOffset)) return null;
int iChunk = Count >> 6;
int iIndex = Count & 63;


if(Chunks[iChunk] == null) return null;
return Chunks[iChunk].Arr[iIndex]; // May be null
}



final public int add(SDL_Surface mySurf)
{
if(Count >= maxSize) return -1;
int iChunk = Count >> 6;
int iIndex = Count & 63;


if(Chunks[iChunk] == null) Chunks[iChunk] = new Chunk(ChunkSize);
Chunks[iChunk].Arr[iIndex] = mySurf;


iIndex = Count;
Count++;
return iIndex; // Return Index/Offset
}



private class Chunk
{
public SDL_Surface Arr[];

Chunk(int iSize)
{
Arr = new SDL_Surface[iSize];
}
}
}


If anyone has the time to convert that, I'd be grateful. :D

-Kramy


imagecache.h:
CODE

#include "file_where_chunk_is_defined.h"

class imageCache
{
public:
imageCache();
~imageCache(){}

bool outOfBounds(int iNum);
// etc

int MaxChunks;
int ChunkSize;
int maxSize;
int Count;
Chunk* Chunks;
};



imagecache.cpp:
CODE

#include "imagecache.h"

imageCache::imageCache()
{
MaxChunks = 16;
ChunkSize = 64;
maxSize = MaxChunks * ChunkSize;
Count = 0;

// this is the C way to do it, it should work in C++ too. If you do this, #include <cstdlib> or just <stdlib.h>
//Chunks = (Chunk*)malloc(sizeof(Chunk) * MaxChunks);

// not sure, I think this works in C++. Long time since I last used C++ ^^;
Chunks = new Chunk(MaxChunks);
}

bool imageCache::eek:utOfBounds(int iNum)
{
return (iNum < 0 || iNum >= maxSize);
}

// etc



CODE

if(Chunks[iChunk] == null) Chunks[iChunk] = new Chunk(ChunkSize);
Chunks[iChunk].Arr[iIndex] = mySurf;



Not sure if 'Arr' is the Java way of handling subarrays, or its a variable in the class/struct 'Chunk'. If it's the first, you'd use: Chunks[iChunk][iIndex] = mySurf;

I hope this should get you started. :)
 
Last edited by a moderator:
Kramy said:
Anyway, I'm a noob when it comes to compiled languages. I have no idea what needs to be fixed. I figured since in C there's no garbage collector, it'd be a good idea to have a big list of all the surfaces loaded into memory, so I can keep track of them, and delete them through that object. Good concept anyway, right?

A good concept, but a bad execution :) (I wouldn't do it this way in Java either).

If you want a variable length array of surfaces, use a vector

imagecache.h

CODE


#include <vector>

class SDL_Surface;

class imageCache
{
public:

std::vector<SDL_Surface*> Chunks;

bool outOfBounds(int iNum);

SDL_Surface* get(int iOffset)
{
if(outOfBounds(iOffset)) return NULL;

return Chunks[iOffset];
}



int add(SDL_Surface* mySurf)
{
Chunks.push_back(mySurf);
return Chunks.size()-1; // Return Index/Offset
}
};




imagecache.cpp

CODE

#include <SDL.h>
#include "imagecache.h"

bool imageCache::eek:utOfBounds(int iNum)
{
return (iNum < 0 || iNum > Chunks.size());
}


SDL_Surface* imageCache::get(int iOffset)
{
if(outOfBounds(iOffset)) return NULL;

return Chunks[iOffset];
}



int imageCache::add(SDL_Surface* mySurf)
{
Chunks.push_back(mySurf);
return Chunks.size()-1; // Return Index/Offset
}





You don't even need imageCache if you're just using it to delete the surfaces at the end, exiting the program will free the memory.
 
Last edited by a moderator:
SharQueDo said:
Not sure if 'Arr' is the Java way of handling subarrays, or its a variable in the class/struct 'Chunk'. If it's the first, you'd use: Chunks[iChunk][iIndex] = mySurf;

I hope this should get you started. :)
Arr was an arbitrary variable name. The beauty of Hotspot is, it compiles a lot of this stuff near identically, so it doesn't matter if I use a class/variable there, or just make Chunks a 2D array.

Chunks[16][] would be equivalent code. ;) Then at the point where it checks for null, you'd just do:

Chunks[iChunk] = new SDL_Surface[ChunkSize];

Interestingly enough, you could initialize every array to a different size, if you wanted, revealing the true "pointer" nature of 2D java arrays.

Anyway, I'm still unclear on how to replicate that in C++. Your changes worked - but I'm not positive they have the same behaviour. :)

Parkydr said:
A good concept, but a bad execution :) (I wouldn't do it this way in Java either).

If you want a variable length array of surfaces, use a vector

Ahh. I really wouldn't use a Vector in java; they're syncronized! All the collections are slower than this(on x86), by somewhere around 20%. I'd rather avoid that 20% hit. Even if my code isn't standard or good, it is fast. ;) (for java)

But it looks like I'll be using vectors for C! :lol:

Edit:
CODE
bool imageCache::eek:utOfBounds(int iNum)
{
return (iNum < 0 || iNum > Chunks.size());
}

Do C++ vectors have the same behaviour as java ones, for the size() method? In java, that should be iNum >= Chunks.size();, because indexes are 0-based.

Edit2: Woohoo! Got it to compile properly. I can see I haven't been using .h files or public: tags properly.
 
Last edited by a moderator:
Parkydr said:
Yes, index is 0 to size-1. It should be iNum >= Chunks.size() as you say. Don't know where the = went.
kk.

The forum ghosts introduced a bug in my get() method too. ;)

Thanks, both of you! Never would've figured out those differences without a working example. :lol:

Edit: One last thing; in C(if it were valid code), would this call the constructor and allocate 8 different objects?
Classname myArr[] = new Classname[8];
 
Last edited by a moderator:
Classname* myArr = new Classname[8];

Will do what you want - the constructor will be called 8 times.

If you delete it you must use

delete [] myArr

or the destructor will only be called on the first element

Note: new/delete is C++ only - not C.
 
Alright, thanks. :) Somehow I thought I needed brackets in the type declaration; I guess you don't for C/C++.
 
You use brackets to pass values to the constructor

e.g.

Classname* myVar = new Classname(8);

makes an instance of Classname calling constructor Classname::Classname(int i)

Same as Java except if there are no parameters to the constructor you just do

Classname* myVar = new Classname;

not

Classname* myVar = new Classname();
 
So how would I go about only initializing 0-1 objects in a size 16 array?


Classname* myArr = new Classname[16];
^
With this code the constructor gets called 16 times; 16 new objects. If those objects have a size 64 array inside them, then it'd be using at least 4096+64 bytes of memory, correct?

The java code I wrote(even though it may not look it) allocates memory as needed. At first, it only uses ~80 bytes; and then after adding 1-64 SDL_Surface objects, it only uses 80+256 bytes.

Oh, and second question - would this be valid?
Classname* myArr = new Classname[16](64);
^
error: ISO C++ forbids initialization in array new

It gives me that error, but there has to be a way to pass params to the objects when initializing a bunch of them, right?
 
Kramy said:
So how would I go about only initializing 0-1 objects in a size 16 array?

Make an array of pointers, then new each object as you need it, that's why I said use a vector.

QUOTE


Classname* myArr = new Classname[16];
^
With this code the constructor gets called 16 times; 16 new objects. If those objects have a size 64 array inside them, then it'd be using at least 4096+64 bytes of memory, correct?




Yes.

QUOTE


The java code I wrote(even though it may not look it) allocates memory as needed. At first, it only uses ~80 bytes; and then after adding 1-64 SDL_Surface objects, it only uses 80+256 bytes.

Oh, and second question - would this be valid?
Classname* myArr = new Classname[16](64);
^
error: ISO C++ forbids initialization in array new

It gives me that error, but there has to be a way to pass params to the objects when initializing a bunch of them, right?



No, not with new.

On the stack you can do stuff like int a[] = {1,2};
 
Last edited by a moderator:
Parkydr said:
Kramy said:
So how would I go about only initializing 0-1 objects in a size 16 array?

Make an array of pointers, then new each object as you need it, that's why I said use a vector.

Yeah, at this point the syntax required to do that makes it more trouble to me than it's worth - I will use vectors. :lol:

Thanks a ton. :)
 
Last edited by a moderator:
Back
Top