How to create and store instances of a class at runtime Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Cheo
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jan 01, 2007 3:45 pm

Post by Cheo » Sun Jan 28, 2007 1:59 am

phlox81 wrote:
Sure you can. I do that every day.
You cannot add them to the Widgets, but you can't do that eather with the wxObjArray.
The STL offers a lot of algorithms and accessiterators for its containers,
which makes me favor them.
Oooops, yes I can. I forgot to add std:: in front of the vector (habit of using namespace std in console programs) :oops:

DavidHart
Site Admin
Site Admin
Posts: 3998
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Sun Jan 28, 2007 11:00 am

Cheo wrote:Ok, now I've added this new class declaration into the header file:

Code: Select all

class HeroManager;
WX_DECLARE_OBJARRAY(HeroManager, ArrayOfHeroes);

class HeroManager {
    public:
        ArrayOfHeroes m_Heroes;
};
Oops, I didn't notice last night, but you're creating an array, not of heros, but of bureaucrats ;) . It should have been WX_DECLARE_OBJARRAY(Hero, ArrayOfHeroes);

The following does compile:

Code: Select all

#include <wx/dynarray.h>

class Hero {
    public:
        int m_Strength;
        int m_Intelligence;
        int m_Dexterity;
        int m_Endurance;
        int m_Personality;
        wxString m_Name;

        Hero(wxString name, int strength, int intelligence,
            int dexterity, int endurance, int personality);

}; 

WX_DECLARE_OBJARRAY(Hero, ArrayOfHeroes);

class HeroManager {
    public:
        ArrayOfHeroes m_Heroes;
};

Code: Select all

// In, e.g.,  the frame constructor

HeroManager manager;
manager.m_Heroes.Add( Hero("David", 100, 1, 1, 1, 1) );
...
}

Hero::Hero(wxString name, int strength, int intelligence, int dexterity,
            int endurance, int personality) {
    m_Name = name;
    m_Strength = strength;
    m_Intelligence = intelligence;
    m_Dexterity = dexterity;
    m_Endurance = endurance;
    m_Personality = personality;
}

Cheo
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jan 01, 2007 3:45 pm

Post by Cheo » Sun Jan 28, 2007 2:34 pm

It does compile in the OnClick funtion of WxButton, which is what I wanted:

Code: Select all

void HeroeFrm::WxButton1Click6(wxCommandEvent& event)
{
    manager.m_Heroes.Add( Hero("David", 100, 1, 1, 1, 1) );

}
=D>

However, the above constructor doesn't compile outside the scope of any function of the Frame source code. But I guess this is a normal behaviour.

Thanks, I may say now problem solved.

DavidHart
Site Admin
Site Admin
Posts: 3998
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart » Sun Jan 28, 2007 4:06 pm

However, the above constructor doesn't compile outside the scope of any function of the Frame source code. But I guess this is a normal behaviour.
Yes. If you want to do this elsewhere, then that function would need a pointer to the frame:
pFrame->manager.m_Heroes.Add( Hero("David", 100, 1, 1, 1, 1) );

Though if that's where you want it done, you'd probably just put the manager instance there instead.

And wherever your HeroManager class is stored, you'll want it as a member, not a local as in my last post. So HeroManager manager; will be in the class declaration, not in the constructor.

phlox81
wxWorld Domination!
wxWorld Domination!
Posts: 1387
Joined: Thu Aug 18, 2005 7:49 pm
Location: Germany
Contact:

Post by phlox81 » Sun Jan 28, 2007 6:42 pm

DavidHart wrote:
However, the above constructor doesn't compile outside the scope of any function of the Frame source code. But I guess this is a normal behaviour.
Yes. If you want to do this elsewhere, then that function would need a pointer to the frame:
pFrame->manager.m_Heroes.Add( Hero("David", 100, 1, 1, 1, 1) );

Though if that's where you want it done, you'd probably just put the manager instance there instead.

And wherever your HeroManager class is stored, you'll want it as a member, not a local as in my last post. So HeroManager manager; will be in the class declaration, not in the constructor.
I think he runs better if he implements this manager as a singleton, that way
you can access it from any point in the application.
Also the array shouldn't be public, the control over the Hero Class instances belongs to the Manager, and no other class.

phlox

Cheo
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jan 01, 2007 3:45 pm

Post by Cheo » Sun Jan 28, 2007 8:35 pm

phlox81 wrote:I think he runs better if he implements this manager as a singleton, that way
you can access it from any point in the application.
That's the intention. However, I'm having problems to access the data members once the instance is created.

Declaring std::vectors and a function to store instances is fine:

Code: Select all

class HeroManager {
    public:
        void Add(const Hero& aHero) {m_Heroes.push_back(aHero);}
        std::vector<Hero> m_Heroes;
        std::vector<Hero>::iterator iter;

};
Then printing the number of intances created is fine:

Code: Select all

    wxString contador;
    manager.Add(Hero(name, strength, intelligence, dexterity, endurance,  personality));
    int cont = manager.m_Heroes.size();
    contador.Printf("%d",cont);
    WxStaticText14->SetLabel(contador);
But what I don't know is how to access a data member.

phlox81
wxWorld Domination!
wxWorld Domination!
Posts: 1387
Joined: Thu Aug 18, 2005 7:49 pm
Location: Germany
Contact:

Post by phlox81 » Sun Jan 28, 2007 8:48 pm

Cheo wrote: That's the intention. However, I'm having problems to access the data members once the instance is created.

Declaring std::vectors and a function to store instances is fine:

Code: Select all

class HeroManager {
        std::vector<Hero> m_Heroes;
    public:
        void Add(const Hero& aHero) {m_Heroes.push_back(aHero);}
        std::vector<Hero>::const_iterator begin()const {return m_Heroes.begin();}
        std::vector<Hero>::const_iterator end()const {return m_Heroes.end();}


};
You don't need the iterator as a class member, the vector itself should be private.
Cheo wrote: Then printing the number of intances created is fine:

Code: Select all

    wxString contador;
    manager.Add(Hero(name, strength, intelligence, dexterity, endurance,  personality));
    int cont = manager.m_Heroes.size();
    contador.Printf("%d",cont);
    WxStaticText14->SetLabel(contador);
But what I don't know is how to access a data member.
Access etc. could and should be implemented in the Manager class itself,
f.e. with an Editmember(int index) method, which launches a Dialog.

Cheo
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jan 01, 2007 3:45 pm

Post by Cheo » Sun Jan 28, 2007 9:40 pm

I cannot declare vector<Hero> m_Heroes private, only public. ???
Access etc. could and should be implemented in the Manager class itself,
f.e. with an Editmember(int index) method, which launches a Dialog.
I understand. I'll work on it.

phlox81
wxWorld Domination!
wxWorld Domination!
Posts: 1387
Joined: Thu Aug 18, 2005 7:49 pm
Location: Germany
Contact:

Post by phlox81 » Sun Jan 28, 2007 9:52 pm

Cheo wrote:I cannot declare vector<Hero> m_Heroes private, only public. ???
sure you can declare it private.
There should be no access to the vector outside of HeroManager.

Cheo
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jan 01, 2007 3:45 pm

Post by Cheo » Sun Jan 28, 2007 11:54 pm

Yes, I can. Again, my fault.

I need to sleep, my head is killing me.

Thanks

Post Reply