🔒 Locked
Pointers to classes
Advertisement
Original Post
hi all,
I am playing around with Class declarations and creating objects
with "new" and I am wondering what the difference between this 2 are: (they both seem to equally work well)
Assuming you have a Class called "ABC":
and in another class you have a pointer which is of type "ABC"
eg. ABC *abc;
So what is the difference between:
abc = &ABC();
and
abc = new ABC();
and they both work fine
quote:
Original post by Xtreme
abc = &ABC();
and
abc = new ABC();
and they both work fine
Dont think I've ever seen the first one before...
But it seems that the first one is allocated staticly and the second dynamicly.
this means that since the second is in dynamicly allocated you need to explicitly delete it, while the first one is delete automaticly when the program exits...
[edit]
tried to correct som horible spelling
[/edit]
/Please excuse my bad spelling - My native language is binary not english
|Visit me
\Take my advice - I don''t use it...
[edited by - guppy on January 7, 2003 1:14:53 AM]
quote:
abc = &ABC();
this will create an ABC object, take it's address, the object will be destroyed and the address assigned to the variable abc.
quote:
they both work fine
by 'work' I assume you mean 'compile'.
You won't be able to actually use the ABC object as it no longer exists. The code doesn't do what you think it does but it is legal c++
For example:
ABC* ptr1 = 0;
{
ABC obj = ABC();
ptr1 = &first
ABC* ptr2 = &first
}
The object 'obj' will remain in scope until the end of the curly braces, after which point it will be destroyed. The pointer 'ptr1' which did point to the object will no longer be valid. The pointer 'ptr2' which also points to obj will also go out of scope and be detroyed at the curly brace so there is no problem there. The compiler will allow you to use 'ptr1' after the curly braces but not 'ptr2'. In effect you have the equivalent of ptr1. It compiles but won't work as you intend.
This is why 'new' is used: if you don't use it the object will be destroyed at the end of the scope. the containers in the standard library can take care of things like that for you so it's possible to hardly ever use 'new'. But, if you want to look after memory and objects that will exist for longer than the duration of a function, then 'new' will be used somewhere.
[edited by - petewood on January 7, 2003 10:19:35 AM]
Petewood, i can understand where your coming from but what if you have the ABC *abc pointer declared as part of your class?
And then use that pointer in one of the methods in your class.
I tried that and it runs fine, and the program does not crash.
For eg.
class DEF
{
DEF(); //default constructor
~DEF(); //default destructor
public:
void DoCalc();
private:
int s;
ABC *abc; //ABC is a class defined elsewhere provided you have the right #defines above
}
And your Default constructor DEF() is:
DEF::DEF()
{
abc = &ABC(); //call the ABC class and assign the address
}
and the DoCalc() is like this:
void DEF::DoCalc()
{
s = abc.getValue();
}
And the result works fine!
The same stuff works with abc = new ABC();
but i need to have delete abc; in the destructor
And then use that pointer in one of the methods in your class.
I tried that and it runs fine, and the program does not crash.
For eg.
class DEF
{
DEF(); //default constructor
~DEF(); //default destructor
public:
void DoCalc();
private:
int s;
ABC *abc; //ABC is a class defined elsewhere provided you have the right #defines above
}
And your Default constructor DEF() is:
DEF::DEF()
{
abc = &ABC(); //call the ABC class and assign the address
}
and the DoCalc() is like this:
void DEF::DoCalc()
{
s = abc.getValue();
}
And the result works fine!
The same stuff works with abc = new ABC();
but i need to have delete abc; in the destructor
this works fine??? do a bit more testing it shouldn''t work that fine. abc is pointing to some stack memory ( and the argument that the pointer is in the class is pointless because it would point to the same memory position if it where e.g. a global variable)
the data members get overwritten regularly by stack activities of the programs (try it!), if there are virtual functions the vtable is also overwritten so the program should crash if you call them in DEF::DoCalc().
GA
the data members get overwritten regularly by stack activities of the programs (try it!), if there are virtual functions the vtable is also overwritten so the program should crash if you call them in DEF::DoCalc().
GA
C++ doesn''t have pointers to classes.
I''ve looked at the source, and there are pieces that are good and pieces that are not ... My experience and some of my friends'' experience is that Linux is quite unreliable. Microsoft is really unreliable but Linux is worse. -- Ken Thompson
I''ve looked at the source, and there are pieces that are good and pieces that are not ... My experience and some of my friends'' experience is that Linux is quite unreliable. Microsoft is really unreliable but Linux is worse. -- Ken Thompson
Xtreme: post real code please
This won''t even compile - let alone run without crashing.
As another poster said, if it works you''re lucky. Or should I say unlucky, because you''re being led to believe that it''s correct, when in fact you can see by our explanations that it''s not.
Don''t rely on a non-complaining compiler or even non-crashing code to satisfy you that your code is correct.
This won''t even compile - let alone run without crashing.
void DEF::DoCalc()
{
s = abc.getValue();// abc is a pointer which
// needs ''->'' to access it
// not ''.''
}
As another poster said, if it works you''re lucky. Or should I say unlucky, because you''re being led to believe that it''s correct, when in fact you can see by our explanations that it''s not.
Don''t rely on a non-complaining compiler or even non-crashing code to satisfy you that your code is correct.
Ok,
I am posting the *real* code below that currently seems to run fine:
The d3ds.h header file:
Note the dtexture.h header file which has a class called Dtexture which is used below:
So does that mean that I'm lucky that this application works?
[edit]
To give you an idea that I ran it and that it didnt crash:
[/edit]
[edited by - Xtreme on January 8, 2003 7:14:42 PM]
I am posting the *real* code below that currently seems to run fine:
The d3ds.h header file:
Note the dtexture.h header file which has a class called Dtexture which is used below:
#ifndef __D3DS__
#define __D3DS__
#include <stdlib.h>
#include <stdio.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "dtexture.h"
.....
class D3ds
{
public:
D3ds(FILE *);
D3ds();
~D3ds();
OGLScene *Read3dsfile(char *);
private:
uint dgetpos();
void * getmem(int);
void dsetpos(uint);
void dread(void *, int);
void OGLFreeScene();
void ReadName(char *, uint);
void ReadObjMeshBlocks(uint);
void ReadObjectBlocks(uint);
void ReadMaterialBlocks(uint);
void ReadTriMeshBlocks(uint, char *);
void ReadFaceMat(uint, OGLObject *);
void ReadMapList(uint, OGLObject *);
void ReadFaceList(uint, OGLObject *);
void ReadVertList(uint, OGLObject *);
void ReadTraMatrix(uint, OGLObject *);
void ReadAmbient(uint, OGLMaterial *);
void ReadAmbientColor(uint, OGLMaterial *);
void ReadDiffuse(uint, OGLMaterial *);
void ReadDiffuseColor(uint, OGLMaterial *);
void ReadSpecular(uint, OGLMaterial *);
void ReadSpecularColor(uint, OGLMaterial *);
void BuildMaterials(OGLObject *);
void UploadTextures();
OGLMaterial * GetMaterial();
OGLObject * GetObject();
Dtexture *tex; //take special note of this
char emsg[100];
FILE *file, *fp;
OGLScene *Scene;
};
#endif
The dtexture.h header file with class Dtexture in case you were wondering:
#ifndef __DTEXTUREH__
#define __DTEXTUREH__
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "ijl15.h"
#define DATA_PATH "data/" //path where the 3ds and textures will be
#define MAX_TEXTURES 300
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
class Dtexture {
public:
Dtexture(FILE *f) : data(0), TextureUploaded(false), file(0), fp(f), texID(0) {} //initialise variables
Dtexture() : data(0), TextureUploaded(false), file(0), fp(0), texID(0) {} //initialise variables
~Dtexture() { CleanUp(); }
uint LoadTexture(char *filename, bool createMipMaps); //returns texture ID
private:
char emsg[100];
bool TextureUploaded; //is the texture loaded into mem?
uint TexList[MAX_TEXTURES]; //texture ID
int width, height, bits; //texture attributes
int texID;
uchar *data; //texture data
ulong texSize; //texture size
ulong size;
uint UploadTexture(bool createMipMaps);
void CleanUp();
void LoadJpg(char *filename);
void LoadBmp(char *filename);
void LoadTga(char *filename);
void LoadPcx(char *filename);
ulong fileSize();
ushort getMemShort(uchar * buffer, int offset);
FILE *file, *fp; //file is used for opening pics and fp is used for debugging to a file
};
#endif
And the d3ds.cpp file which makes use of the Dexture class with *tex pointer:
Please look at the function UploadTextures() below which makes use of *tex:
#include "d3ds.h"
/*******************************************************************************************/
D3ds::D3ds(FILE *f)
{
Scene = NULL;
fp = f;
}
/*******************************************************************************************/
D3ds::D3ds()
{
Scene = NULL;
fp = NULL;
}
/*******************************************************************************************/
D3ds::~D3ds()
{
OGLFreeScene();
}
/*******************************************************************************************/
..........
void D3ds::UploadTextures()
{
OGLMaterial* mat;
uint texID;
int tcount =0, tfail =0;
if (fp) fprintf(fp, "\n%d materials loaded\n", Scene->materials);
for (int n=0; n < Scene->materials; n++)
{
mat = &Scene->matlist[n];
if (strlen(mat->filename) > 0) //is a texture map defined?
{
if (Scene->tex == NULL) //allocate memory for Dtexture class
{
Scene->tex = &Dtexture(fp);//notice how I call the constructor and initialised the object *tex*
if (Scene->tex == NULL)
throw "Cannot allocate memory for the texture class";
}
texID = Scene->tex->LoadTexture(mat->filename, 1);
if (texID == 0xFFFFFFFF) {
mat->texUploaded = false;
mat->texID = 0;
tfail++;
}
else {
mat->texUploaded = true;
mat->texID = texID;
}
tcount++;
}
}
if (fp) fprintf(fp, "%d textures loaded\n", tcount-tfail);
if (fp && (tfail > 0)) fprintf(fp, "Failed to load %d textures\n", tfail);
}
And to confirm that it compiles and links fine (and runs fine but I cant show you that it works here)
--------------------Configuration: OGLCrystal - Win32 Release--------------------
Compiling resources...
Compiling...
demo.cpp
dmath.cpp
main.cpp
winapp.cpp
bands.cpp
tubes.cpp
d3ds.cpp
dtexture.cpp
sound.cpp
Linking...
OGLCrystal.exe - 0 error(s), 0 warning(s)
So does that mean that I'm lucky that this application works?
[edit]
To give you an idea that I ran it and that it didnt crash:
[/edit]
Loaded 'C:\tmp\Release\OGLCrystal.exe', no matching symbolic information found.
Loaded 'C:\WINNT\System32\ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\USER32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\KERNEL32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\GDI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\msvcrt.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\OPENGL32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\ADVAPI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\rpcrt4.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\glu32.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\ddraw.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\dciman32.dll', no matching symbolic information found.
Loaded 'C:\tmp\ijl15.dll', no matching symbolic information found.
Loaded 'C:\tmp\BASS.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\winmm.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\msacm32.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\OLE32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\mmdrv.dll', no matching symbolic information found.
The thread 0xB94 has exited with code 0 (0x0).
The program 'C:\tmp\Release\OGLCrystal.exe' has exited with code 0 (0x0).
[edited by - Xtreme on January 8, 2003 7:14:42 PM]
quote:
I tried that and it runs fine, and the program does not crash.
A real world analogy:
You have a gun, a six-shooter with 3 bullets, but you have no idea in which chambers those bullets lie. You have just picked up the gun, put the tip in your ear, and pulled the trigger.
What do you think will happen with the next pull of the trigger?
null_pointer,
I know what you mean. Your saying that it may not crash now, but it may when you least expected it.
But my question is, if there was a bug,
then wouldnt the application come up with an Access Violation (0xc000000) or whatever?
[edited by - Xtreme on January 8, 2003 7:30:49 PM]
I know what you mean. Your saying that it may not crash now, but it may when you least expected it.
But my question is, if there was a bug,
then wouldnt the application come up with an Access Violation (0xc000000) or whatever?
[edited by - Xtreme on January 8, 2003 7:30:49 PM]
quote:
I tried that and it runs fine, and the program does not crash.
I think what they are trying to get at is that your program might not crash, because there is data where you are trying to access it, but the way that you are handling your pointers allows other programs to overwrite that data. If they do, you will have logic errors.
Your program may run so fast or its memory may be secluded enough that other programs don''t get to your memory and botch it up, but if you use the "ptr = &obj" method extensively in a large program, I think you may find circumstances that are not so "lucky".
Here''s my analogy:
int s = 5;
int *t;
t = &s
So in this case, the program allocates memory for s to store "5", then you declare a pointer ''t'' of type int and in the 3rd line you store the address of where the variable ''s'' is.
So in my case,
I declare a pointer of type class and assign the address of the object that it created.
int s = 5;
int *t;
t = &s
So in this case, the program allocates memory for s to store "5", then you declare a pointer ''t'' of type int and in the 3rd line you store the address of where the variable ''s'' is.
So in my case,
I declare a pointer of type class and assign the address of the object that it created.
quote:
Original post by null_pointer
A real world analogy:
You have a gun, a six-shooter with 3 bullets, but you have no idea in which chambers those bullets lie. You have just picked up the gun, put the tip in your ear, and pulled the trigger.
What do you think will happen with the next pull of the trigger?
The second person has a chance of 33.3% to die.
[edited by - kspbergstrom on January 8, 2003 7:51:37 PM]
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement