Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: Clyde on October 24, 2014
-
Hi,
I'm trying to use pointers with classes, but not alot of luck. I remember mentioned sometime ago about making them static, but not really sure on that.
The errors I'm graced with are:
cx0030: Error: expression cannot be evaluated
and then for every element / variables in that particular class, there are loads of question mark, eg. wwidth=??????, height=??????
Hugest of thanks for your time and any help.
Clyde.
-
Hello
Don't worry (or don't panic !)
First, when I opened the main.cpp I saw something that is going to hurt.
Let's see :
gfx_buffer* screen_buffer;
screen_buffer->graphics( "p01n3trz t3st", 640,480);As I told you, this, when running, will crash immediately. I will try to explain it.
screen_buffer, is a pointer to a gfx_buffer. Well, that's fine. But, I pointer is just like, an arrow pointing on something. Here, you don't point on anything and you are trying to use (second line : screen_buffer->graphics(...)) your "pointer on whatever".
It's a bit like having a mail adress as follow :
vdus<ovn oudsnv
vndusnvsduvsnuo
vndsuivd
Try to reach this :D
And computers are dumb. They will try. More precisely, in fact, screen_buffer does contain a value. Sometimes (when running in Windows debugger) it is 0 (or NULL). Sometimes, it is random. But everytime, it is not what you want.
When you are trying to do : screen_buffer->... (trying to use the pointer) and that it contains 0, it crash (everytime). Since 0 is not a valid pointer.
With random value, it depends on operating system and CPU. Since the random value can point memory that you own, it will not crash, but it is likely to crash (now or later).
So, first advice : Always give a value to a new variable. Trust me, uninitialized variables are not your friends. Uninitialized pointers (since these are variables more or less as others) as to be initialized.
When you don't know which value to use, put 0. It will help you, at least by crashing the program immediately (but the bug will be more visible than just random behaviour).
Ok, it was the first part.
A pointer, litteraly, it's a memory address. It's just a memory address that we put in a variable and that we can follow to reach the memory (or an object stored in memory, or a variable stored in memory).
When you see a pointer :
int* pA = NULL; It just means this is a pointer, that will point on a int. So, if you follow the address in the pointer (ok, here, the address is 0 and it will crash), you will find a variable of type int.
More precisely :
int myVar = 42;
int* pMyVar = &myVarHere, I have a variable called "myVar" which contains 42. Ok, it means, in some way, that the computer stored 42 in its memory.
Now, the second line.
&myVar means -> the addresse of myVar.
So, pMyVar, is a pointer leading to a int, which is initialized to the address of myVar. It means, that, when I will follow the pointer (*pMyVar), it will lead me to 42 :)
Second advice : to differentiate the variables with the pointers, I am using a "special" syntax. All my variables that are pointers, are called beginning with 'p'.
At least, it will help me to see if I have to use '.' or '->' syntax.
So, let's go back to your main.cpp
The point is that you have never initialized your pointers. You will have to do it, at the beginning of the main.
To allocate some memory (meaning, telling to the system the program wants to use some memory cells for its own usage), you will use "new" (it's a C++ keyword).
When you want to release the memory (meaning, telling to the system, the program does not need this memory anymore), you will use "delete".
So, at some point, at the very beginning of main, you will see :
screen_buffer = new gfx_buffer();Here, it allocates the space needed for a gfx_buffer, and new will return you, the address of this new storage that the OS allowed you to use.
At the very end of main, you will see :
delete screen_bufferWhich will call the destructor of your gfx_buffer.
Well, I saw your graphics function and I am understanding that you want to do.
You have to put graphics() and create_gfx_graphics() as static. Otherwise, you will have to do the "new" call.
Why ?
Because you can't use your gfx_buffer, since it needs to be initialized to be used. A static function can be used without initializing (creating) any of the class instance
Otherwise, you can also do the "graphics() function stuff" in the constructor of the class. Which sounds proper
I will stop here for now. Tell me if it is becoming understandable, or not.
Don't hesitate to ask more and more ;)
-
thanks LittleWhite :)
it's funny that when you make a standard class without being pointers, screen_buffer.graphics("title",640,480); seems to have no quarrels,
but as soon as you start using and returning pointers, c seems to have dementia.
I put static infront of any functions that make and return a new gfx_buffer; and seems to be doing the trick. :)
And then when creating any of them screen_buffer::gfx_buffer=graphics();
another funny thing i ran into when debugging, is that most of my variables that are floats get rounded, for instance: float value=0.08f get turned into 0.079f
and some are incredibly big with e's in them, -2.3753892e-005f. I also need to round to the nearest integer when I'm drawing. int x=(int)float_x;
Next question, is there a tidier looking way to rephrase for example image::gfx_buffer=create_gfx_buffer();
is there something you can do with namespace to get rid of the double colons and the class name part, ::name_of_class= ?
Cheers!! :)
-
Well, if you want to get rid of the notation : namespace_name::class, you can use :
using namespace namespace_nameIt means that the compiler can look in this namespace, to search for symbols.
But, be careful, using this code in a header can bring you some hurt, since the header is a file which is included (literally, copied) and so, the using namespace can propagate in every file including the header. In one word : don't put using namespace in a header :D
-
class without being pointers seems to have no quarrels, but as soon as you start using and returning pointers, c seems to have dementia
Please have a look into this fine tutorial on pointers (http://alumni.cs.ucr.edu/~pdiloren/C++_Pointers).
float value=0.08f get turned into 0.079f
That's the wonderful magic of IEEE 754 floating point numbers :)
Unlike integers, the steps between two adjacent floats are dynamic.
So there's always some kind of gap between two numbers and it's unlikely to actually hit precisely the one you wanted.
That's why for example:
1.33300000f is 1.3329999
1.33300001f is 1.33300006
More confusion is caused by the fact that floats are internally stored to the base of 2:
+/- [1.0 ... 2.0] * 2 ^ e
(A positive "e" makes the value larger and a negative "e" makes the value nearer to zero).
But if you display a float, you'll typically use the decimal system.
So it's converted back from base-2 to base-10 and only shows an approximation of the actual base-2 representation.
However, if you apply some reasonable amount of rounding, you often won't even notice the difference...
-
is this the same for glFloats ?
-
It is *exactly* the same for GLfloat - or to quote <gl.h>:
typedef float GLfloat;