Sign in to follow this  
dawidjoubert

Pointers & C++, Intermediate

Recommended Posts

Is it possible to link from data source to each other using pointers, check example. class Face { vertices normal color texture // Reference to its parent Object *parent; }; class Object { numfaces Face *faces; // the actual faces } // Now in the example the structure looks simple but in my project most things are in lists or vectors so what happens is when a face is created the parent pointer should be set to the object so that when a face undergoes a transformation or a change and it requires more information then it can look to the parent. a good example of this is when extruding a face. the parent is required because n new faces are created to form the height or extrusion of the new face, Also other operations like subdivide and split Thanks

Share this post


Link to post
Share on other sites
as far as i know of no... i just tryed it using two test classes and i got a type name expected error on Object *Parent line, which i had a feel would happen because i thought i had once tryed the same thing... its because you try to create a variable of a type that has not been defined yet unless you could define two classes at the same time...

Share this post


Link to post
Share on other sites
Yeah, it's possible. In order to get it to work, you need to use forward declarations for the classes, like this:

In Face.h:

class Object;
class Face
{
/* pointers are all the same size, so the compiler doesn't need to know what Object really is, just that it's a class and you have a pointer to it. */
Object *parent;
}

In Face.h:

#include <Face.h>
#include <Object.h> // here is where you tell the compiler what Object is

void Face::SomeFunction()
{
parent->DoSomethingWithTheParent();
}


You can then do the same process for Object. Just do "class Face;" before you define Object, and then include Face.h in Object.cpp, and you should be good to go.

However, one note, you can't do something like this:

class Object;
class Face
{
Object obj;
}

Because the compiler needs to know the size of the Face class at compile time, it won't let you use an undefined class as a member. But using a pointer or reference to a class that's only been forward declared is fine.

Share this post


Link to post
Share on other sites
Never tried, but put a

class Object;

before the declaration of Face so that Object is already known by the compiler before it gets to know Face. The full declaration of Object can stay right where it is.

Might work :-)

EDIT: Damn, a bit to late :-)

Share this post


Link to post
Share on other sites
i just clicked post at which i posted quite some on why it can be done and that pointers only point to addresses. The real reason being is i dont have any formal c++ training only years experience in programming so some small stuff like this i miss out.

Would it be okay to do it this way

class CFace;
class CVertex;
class CObject;
////
class CVertex
{
cface *face
cobject *object
}
class CFace
{
cvertex *vert;
cobject *object
}
class CObject
{
cface *face;

}

Share this post


Link to post
Share on other sites
You *can* use forward declarations, but if possible try to avoid them because it usually indicates that something is wrong in your code (or rather, there is probably a better way).

to use the previous example....


class CFace;
class CVertex;
class CObject;
////
class CVertex
{
cface *face
cobject *object
};
class CFace
{
cvertex *vert;
cobject *object
};
class CObject
{
cface *face;
};


The problem is that each pointer will be 4bytes in size. This makes your vertex structure 20 bytes with pointers, 12 bytes without. Since there will be a lot of vertices, it would cost a fair amount of data. In this case, it may be better to consider storing indices rather than pointers since you might be able to get away with unsigned shorts (2bytes each, thus sizeof(cface) == 16). You could even use bitfields to store the indices, ie)


class CVertex
{
struct {
unsigned short face_index:20;
unsigned short obj_index:12;
};
};


This would still be 4 bytes for the 2 indices, however you'd now be able to index 1048576 vertices and 4096 objects rather than 65536 verts, 65536 objects.

If you start using indices, then obviously the vertices loose the ability to directly reference the faces or objects. To get around that, you probably want to transfer any functions that need to reference both the vertex and face into the object structure. That way the object is responsible for any direct references to IT'S OWN data (and can check things like if the pointer is valid).

Share this post


Link to post
Share on other sites
Quote:
Original post by RobTheBloke
You *can* use forward declarations, but if possible try to avoid them because it usually indicates that something is wrong in your code (or rather, there is probably a better way).

Nonsense, there are plenty of occasions where forward declarations are perfectly valid. For example a parent/child relationship where both classes need a pointer to each other.

Forward declarations are however a symptom of C++'s retarded single-pass compilation model.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
Quote:
Original post by RobTheBloke
You *can* use forward declarations, but if possible try to avoid them because it usually indicates that something is wrong in your code (or rather, there is probably a better way).

Nonsense, there are plenty of occasions where forward declarations are perfectly valid. For example a parent/child relationship where both classes need a pointer to each other.

Forward declarations are however a symptom of C++'s retarded single-pass compilation model.


.... however, should the child be required by other classes independantly, you are forced to either check for a NULL parent or duplicate code (either via copy & paste, or the use of a template).

Either way, it still causes additional bloat that really should not be there.

[edit]This is more of a bug bear of mine having gained experiance of what happens a year down the line on a large project[/edit]

Share this post


Link to post
Share on other sites
There is absolutely nothing wrong with forward declarations. In fact there are many situations where they are very useful, for example the pimpl idiom where they are used to reduce dependencies and increase security:
class MyClassImpl;

class MyClass
{
public:
// member functions
private:
boost::shared_ptr< MyClassImpl > pimpl_;
};

Here the implementation of MyClass is hidden behind the opaque pimpl_ pointer, making MyClass a lightweight class with few dependencies. If the implementation of MyClass changes but the interface remains the same then only MyClassImpl.cpp needs recompiling.

Enigma

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this