I can't seem to find the answer but maybe I'm searching the wrong terminology. I am not finding the answer I am looking for in the hits.
I have a bunch of derived classes for a menu system.
I have a CControl
derived class that is parent of a CEditBox
and a CLabel
class. CLabel
is nothing more than attaching the text onto an SDL_Surface and then binding it to a texture for openGL to render. CEditBox
would be a field for displaying text or gathering text from users like a password box. Obviously, CEditBox could make use of a label for handling the text rendering inside the box. CControl
is derived from CComponent
.
I cannot declare CLabel
inside CEditBox
unless I include CLabel
in the header but I think I keep getting linker errors doing that even though I have all of my headers wrapped in #ifndef #define class #endif
syntax but I'm also a noob. Instead, I have a CComponent*
pointer declared since they are derived from that class.
Fine. Now in the constructor for the CEditBox
I have:
#include "CLabel.h" //include in .CPP is fine I reckon.
CEditBox::CEditBox() {
CLabel Field; //Create CLabel
InputType = ALL; //Not important for my question related to allowed symbols
Label = &Field; //CComponent pointer to CLabel
}
When this constructor function returns, wouldn't CLabel go out of scope, and thus Feild would be destroyed and now my pointer is pointing at an undefined block of memory? What would be an appropriate way to do this? Is there a better solution?
Thank you
Linker problem
I don't know that the problem exists anymore, but some think this is a more important issue. Well here is the actual code now and you guys can tell me if you think it is done incorrectly. Base Class CMenuObject
#ifndef _CMENUOBJECT_H_
#define _CMENUOBJECT_H_
class CMenuObject {
protected:
const char* ClassName;
public:
CMenuObject();
virtual const char* Object();
};
#endif
Next Class is CComponent
#ifndef _CCOMPONENT_H_
#define _CCOMPONENT_H_
#include "CMenuObject.h"
class CComponent : public CMenuObject {
protected:
const char* _Name;
int _Tag;
static int _ComponentCount;
static int _IDCount;
public:
CComponent();
virtual const char* Name();
virtual int Tag();
virtual void Tag(int t);
};
#endif
Then comes CControl These would be objects that users would interact with or in some way need control the display (i.e. a timer doesn't need user input) and is a mammoth. Don't mind the function pointer stuff because I have no idea what i'm doing with that yet.. this is my first guess approach to handling events. I think it's limiting because I can't figure out what to do if the function needs to take a parameter but I may not have to, etc... We can gloss over this detail for now.
#ifndef _CCONTROL_H_
#define _CCONTROL_H_
#include "CComponent.h"
class CControl : public CComponent {
protected:
int _X,_Y,_Width,_Height;
float R,G,B,A;
void (*OnClk)();
void (*OnDblClk)();
void (*OnMOver)();
void (*OnMHover)();
void (*OnKDown)();
void (*OnKUp)();
void (*OnFcs)();
bool Visible;
CComponent* Pappy;
public:
CControl();
//Render Control
virtual void Show(); // Show Component
virtual void Hide(); // Hide Component
virtual void OnRender(); // Render Component
virtual bool IsVisible(); // Get Current Visibility Status
//Paramater Control
//Write
virtual void X(int x); // Set Component's X coordinate
virtual void Y(int y); // Set Component's Y coordinate
virtual void Width(int w); // Set Component's Width
virtual void Height(int h); // Set Component's Height
//Read
virtual int X(); // Get Component's X coordinate
virtual int Y(); // Get Component's Y coordinate
virtual int Width(); // Get Component's Width
virtual int Height(); // Get Component's Height
//Display Control
virtual void Color(float r, float g, float b); // Set Color of Component- Multicolored objects, this will be the base or bkg color. Makes alpha 1.0f.
virtual void Color(float r, float g, float b, float a); // Same as above but allows for input of an alpha value.
//Font Control
virtual void FontName(const char* font); // Name of font to use
virtual void FontSize(int pt); // Pt size of font. Or maybe pixel, no idea.
virtual void Text(const char* msg); // Text message to render
//Read
virtual const char* Text(); // Read Text Message
//Interactive Control // These will register call back functions for user events
virtual void OnClick(void (*func)()); // On Single Click
virtual void OnDoubleClick(void (*func)()); // On Double Click
virtual void OnMouseOver(void (*func)()); // On Mouse Over
virtual void OnMouseHover(void (*func)()); // On Mouse Hover
virtual void OnKeyDown(void (*func)()); // On Key Down
virtual void OnKeyUp(void (*func)()); // On Key Up
virtual void OnFocus(void (*func)()); // On Focus
//Other
virtual void Parent(CComponent); // Set Parent
virtual CComponent* Parent(); // Get Parent
};
#endif
Finally my end game headers of CLabel and CEditBox.
#ifndef _CLABEL_H_
#define _CLABEL_H_
#include "CTexture.h"
#include "CFont.h"
#include "CControl.h"
class CLabel : public CControl {
private:
const char* vText;
CFont Font;
CTexture Text_Font;
SDL_Surface* Surf_Text;
int X,Y,vWidth,vHeight;
public:
CLabel();
CLabel(const char* text);
virtual void OnRender();
virtual void OnCleanup();
virtual void Text(const char* msg);
virtual const char* Text();
virtual void FontName(const char* fname);
virtual void FontSize(int pt);
virtual void FontColor(float r, float g, float b);
};
#endif
AND
#ifndef _CEDITBOX_H_
#define _CEDITBOX_H_
#include "CControl.h"
class CEditBox : public CControl {
protected:
CComponent* Label;
int InputType;
public:
CEditBox();
~CEditBox();
virtual void OnRender();
//virtual void OnCleanup();
virtual void OnLoop();
virtual void Text(const char* msg);
virtual const char* Text();
virtual void FontColor(float r, float g, float b);
virtual void OnClick(void (*func)()); // On Single Click
virtual void OnDoubleClick(void (*func)()); // On Double Click
virtual void OnMouseOver(void (*func)()); // On Mouse Over
virtual void OnMouseHover(void (*func)()); // On Mouse Hover
virtual void OnKeyDown(void (*func)()); // On Key Down
virtual void OnKeyUp(void (*func)()); // On Key Up
virtual void OnFocus(void (*func)()); // On Focus
enum {
ALL = 0, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890!@#$%^&*()_+-=[]{}<>\/|"';:,.?
ALPHA_NUMERIC, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890
ALPHA, //abcdefghijklmnopqrstuvwxyz (and caps)
NUMERIC, //1234567890
PASSWORD, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890!@#$%&. -- Render as *
IP //1234567890 . Maybe fix feild width and force xxx.xxx.xxx.xxx format.
};
};
#endif
[SOLVED]
Today, I found the one dang header not wrapped in #ifndef #define #endif. (it was CTexture
which gets called again in CFont
. Anyway, the restructure was also incredibly beneficial because I've figured out how to use inheritance and base class pointers, and how derived classes can work with each other. Not to mention many many more things. :)
The route I'm taking for derived class interplay is using a base class pointer that can access the derived classes functions via virtual functions. I use new and delete because that's what I am comfortable with. For everyone that contributed, thank you! They are all good answers.