Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointers, Class Items and Scope

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.

like image 495
Chemistpp Avatar asked Jun 20 '13 15:06

Chemistpp


People also ask

What is the scope of a pointer?

If you create a pointer variable using dynamic memory allocation (with the word new), its scope is the end of the block (the next closing bracket) like any other variable.

What is the scope of class objects?

An object is visible in a block or source file if its data type and declared name are known within the block or source file. The region where an object is visible is referred to as its scope.

What is a class scope?

When you declare a program element such as a class, function, or variable, its name can only be "seen" and used in certain parts of your program. The context in which a name is visible is called its scope. For example, if you declare a variable x within a function, x is only visible within that function body.

What is class scope in OOP?

Scope means that the method or variable may or may not be directly accessible to other objects or classes. Classes that do not have instances may be accessible to the system. Class Scope: Class variables and class methods are associated with a class.


2 Answers

Stereo typical approaches would be:

  • the pimpl idiom (Why should the "PIMPL" idiom be used?)
  • using unique_ptr (Rule of Zero)

Showing the second approach:

//////////// CEditBox.hpp header file
#include <memory>
#include <string>

class CLabel; // forward declaration

class CEditBox
{
  public:
    CEditBox(std::string const&);
  private:
    std::unique_ptr<CLabel> _label;
};

The forward declaration avoids the need to include CLabel.hpp. The unique_ptr manages the lifetime _label so we don't have to remember to delete it.

//////////// CLabel.hpp header file

#include <string>
#include "CLabel.hpp"

class CLabel
{
  public:
    CLabel(std::string const& name) 
        : _name(name) 
    {
    }
  private:
    std::string _name;
};

Just a sample, nothing to see here. Let's move on:

///////////// CEditBox.cpp source file

#include "CEditBox.hpp"
#include "CLabel.hpp"

CEditBox::CEditBox(std::string const& name)
    : _label(new CLabel(name)) 
{
}

That's the magic: we integrate it all by include CLabel.hpp as well, and construct it in the initializer list.

///////////// main.cpp source file

#include "CEditBox.hpp"

int main()
{
    CEditBox box("Hello world"); // no need to 'know' CLabel here   
}

Proof of the pudding is in the compilation: http://ideone.com/zFrJa8

like image 60
sehe Avatar answered Sep 19 '22 22:09

sehe


Your thinking is on the correct track. The right approach would be allocating this object dynamically, i.e.

Label = new CLabel;

Don't forget to free memory in destructor:

delete Label;
like image 20
Andrejs Cainikovs Avatar answered Sep 19 '22 22:09

Andrejs Cainikovs