[C++] Unknown data type

Started by
16 comments, last by Decrius 15 years, 10 months ago
Since users can bind data to certain classes, of varying type, I thought I'd use void pointers. But this isn't really going to work. Maybe using templates would be correct, but since I don't know the data type at start, I have no idea what data type I should give it on initialisation.
    class Component
    {
    public:
        Component();
        ~Component();
        
        void set_data(void *idata);

        void *data;
    };

    Component::Component()
    {
        data = NULL;
    }

    Component::~Component()
    {
        delete data;
    }

    void Component::set_data(void *idata)
    {
        delete data;
        data = new void;
        *data = *idata;
    }

    int main()
    {
        Component component;

        int data = 21;
        component.set_data(&data);
    }


This is ofcourse not going to work, but it shows you where the problem is. What would be a good way to solve this? Should I use a class, which users can derive? Should I use templates (which I generally dislike...)? Anything else? Thanks!
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Advertisement
This is a perfect example of the use of templates.

template<typename T>class Component{public:    Component(){ data = 0; }    ~Component(){ delete data; }    void setData(T& newdata){ delete data; data = &newdata; }    T& getData() const { return *data; }private:    T* data;}


(This class has problems with ownership, what happens if i delete an object i have passed to setData? It will get deleted twice, be very careful with this class...)

Why do you not like templates? I am almost certain whatever it is, it is either a myth, or easily solved. Templates are very useful in the right situations (like this one).

[edited - variable name clash]
What about boost.variant or boost.any?
Quote:Original post by Decrius
Should I use a class, which users can derive? Should I use templates (which I generally dislike...)? Anything else?

What is it you're really trying to do with this?
What is this binding for and why do you need a variant type?
Quote:Original post by sphen_lee
This is a perfect example of the use of templates.

*** Source Snippet Removed ***

(This class has problems with ownership, what happens if i delete an object i have passed to setData? It will get deleted twice, be very careful with this class...)

Why do you not like templates? I am almost certain whatever it is, it is either a myth, or easily solved. Templates are very useful in the right situations (like this one).

[edited - variable name clash]


Thank you.

What I dislike about it, is that you have to put this in the end of your script to make it actually work:

template void Container::add<Button::Texture>(std::string name, Button::Texture &iitem);


This would enable the use of the Button::Texture class, to be passed onto the Container::add() function.

Maybe it's me, and my lack of knowledge in templates, but I had to use it, else I'd get errors (has it to do with the reference? if I'd use pointers would this not be needed?)

Quote:Original post by rip-off
What about boost.variant or boost.any?


Thanks rip-off :), will look into it.

Quote:Original post by dmatter
Quote:Original post by Decrius
Should I use a class, which users can derive? Should I use templates (which I generally dislike...)? Anything else?

What is it you're really trying to do with this?
What is this binding for and why do you need a variant type?


I'm trying to make a GUI system (I was not pleased with original ones). Components are items in the GUI (button, textfield, scrollbar). Whenever an event occurs (click, move, key press), the component that is effected/affected (my english is bad '-.-) will put the pointer to it's data variable into the Event class. This way the user can indentify (or actually, use the data since indentifying can also be done via the components name the user has given it) which component has an event and thus build actions around it.

Since I don't know what data is passed (either an int, a char *, a struct, a class...) I had to build something for that.

I will implement the templates, but, sphen_lee, wouldn't your example require the type to be set on initialisation of the object?

Thanks for your posts ;)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
I'm trying to make a GUI system (I was not pleased with original ones). Components are items in the GUI (button, textfield, scrollbar). Whenever an event occurs (click, move, key press), the component that is effected/affected (my english is bad '-.-) will put the pointer to it's data variable into the Event class. This way the user can indentify (or actually, use the data since indentifying can also be done via the components name the user has given it) which component has an event and thus build actions around it.

That sounds rather convoluted. Wouldn't the event handler already know what component or at least what type of component it's serving? Wouldn't it be better to have a pointer to the Component itself in the Event instance?
Quote:Original post by SnotBob
That sounds rather convoluted. Wouldn't the event handler already know what component or at least what type of component it's serving? Wouldn't it be better to have a pointer to the Component itself in the Event instance?


Yes, actually I left out the boring details, but I practically do what you say.

And no, the event does not know which component it is serving until I go through all (/some) objects to determine which component is clicked (this is done using a Rect of the component, and mouse pointer (in case of a mouse event) coordinates).

Since it's rather long to post all details I leave them out, however, in the near future I plan on releasing it. Then I will post all details ;)

[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by sphen_lee
(This class has problems with ownership, what happens if i delete an object i have passed to setData? It will get deleted twice, be very careful with this class...)


So... Just test to see if datais null or not before deleting it...

I'll replace:

Component(){ delete data; }

by:

Component(){ if(data){ delete data; data = NULL} }

Cheer!
Quote:Original post by Vortez
Quote:Original post by sphen_lee
(This class has problems with ownership, what happens if i delete an object i have passed to setData? It will get deleted twice, be very careful with this class...)


So... Just test to see if datais null or not before deleting it...

I'll replace:

Component(){ delete data; }

by:

Component(){ if(data){ delete data; data = NULL} }

Cheer!


int * x = NULL;
delete x; // perfectly legal and safe

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Quote:Original post by Vortez
Quote:Original post by sphen_lee
(This class has problems with ownership, what happens if i delete an object i have passed to setData? It will get deleted twice, be very careful with this class...)


So... Just test to see if datais null or not before deleting it...

I'll replace:

Component(){ delete data; }

by:

Component(){ if(data){ delete data; data = NULL} }

Cheer!


Yeah, but what if you have something like this:

Component::Component(int *pointer){    data = pointer;}Component::~Component(){    delete data;}int *pointer = new int(6);Component component = Component(pointer);delete pointer;


Therefor I use this (just copy the value):


Component::Component(int *pointer){    data = new int(*pointer);}Component::~Component(){    delete data;}int *pointer = new int(6);Component component = Component(pointer);delete pointer;


----

I'm trying to use boost::any, since with templates I need to initialise the type on initialisation of the class, however this is what I get:

E:\C\OpenGUI\main.cpp:63: error: no matching function for call to `Button::Texture::set_data(Data&)'E:/C/OpenGUI/opengui/component.h:29: note: candidates are: void Component::set_data(boost::any&)


And yes, Button::Texture is derived from Component. Only Component holds the set_data function, which looks like this:

    class Component    {    public:        Component();        virtual ~Component();               void set_data(boost::any &idata);    private:        boost::any *data;    };    void Component::set_data(boost::any &idata)    {        delete data;        data = new boost::any(idata);    }
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora

This topic is closed to new replies.

Advertisement