CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    May 2003
    Location
    Corvallis, OR
    Posts
    315

    an alternative to enum{}

    I tend to use enum{} like it's going out of style. Anytime I have a collection of objects that can have 1 of many different identifiers I go to the good old enum.
    My latest example is as follows..

    I have created a CListbox derived object. Each item in the list box can be one of 3 different types (lets say typeThis, typeThat, typeTheOther). I would typically define an enum in the CListbox object's header.
    Code:
    enum type {typeThis = 0, typeThat, typeTheOther};
    Next I would store the value as a DWORD and place it in the ItemData of the newly inserted item.
    Code:
    DWORD dwItemType = (DWORD)typeThat;
    m_list.SetItemData(nNewIndex,dwItemType);
    Finally, when I need to know what type of item I am dealing with, I can enumerate through my list box and check out all of the item types and act accordingly.
    Code:
    CMyListBox::DoStuff()
    {
    	for(int index = 0; index < GetCount(); index++)
    	{
    	   type itemType = (type)GetItemData(index);
    	   switch(itemType) 
    	   {
    	   case typeThis:		
    			//do stuff specific to typeThis
    		break;
    	   case typeThat:		
    			//do stuff specific to typeThat
    		break;
    	   case typeTheOther:		
    			//do stuff specific to typeTheOther
    		break;
    	   default:
    			ASSERT(false);  //undefined type
    	}
    
    }
    Is this the best way to accomplish this task? Basically I use enum like a multi-state boolean. Maybe there is a method that I am not aware of?

  2. #2
    Join Date
    Dec 2004
    Location
    Ann Arbor, MI
    Posts
    281

    Re: an alternative to enum{}

    I think that method is fine. I use a lot of enumerated values as well. I know some people that use #defines like THEY are going out of style, but I think enums are better for these types of things because they can be scoped (classes, namespaces, etc).
    --EJMW

  3. #3
    Join Date
    Nov 2001
    Posts
    323

    Re: an alternative to enum{}

    The only alternative I can think of is to use virtual functions.
    Apparently you can replace 99% of all 'if/else' and switch statements with virtual functions.
    Best Regards,

    --Zim
    If you find this post useful, please rate it.
    _________________________________
    "Have you the brain worms?!?!?"

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Post Re: an alternative to enum{}

    Your approach seems fine. Another approach is to use the data pointer to store an instance of a class, then in the DoStuff() you would cycle through each list item, retrieve the class pointer for the item, and call a DoStuff() method for the object.

    Use can use the enum method from within the class to distinguish the object istances or you could get fancy and create a base class with a pure virtual DoStuff() method and derived classes that represent each enum constant (providing there is enough differences between the enums to warrant a separate class implementation).

    Declare simple this and that classes with a base class
    Code:
    class CListItemBase
    {
    // ctor/dtor
    CListItemBase();
    virtual ~CListItemBase();
    protected:
    virtual HRESULT DoStuff() = 0;
    };
     
    class CListItemThis : public CListItemBase
    {
    // ctor/dtor
     
    public:
    virtual HRESULT DoStuff(); // This specific stuff
    };
     
    class CListItemThat : public CListItemBase
    {
    // ctor/dtor
     
    public:
    virtual HRESULT DoStuff(); // That specific stuff
    };
    Create the some class instances, and set the list box data. Note the use of SetItemDataPtr instead of SetItemData.
    Code:
     
    // These objects are declared to have object scope
    // Typically these could be stored in a CTypedPtrList or std::list.
    CListItemThis m_pLIThis = new CListItemThis();
    CListItemThat m_pLIThat = new CListItemThat();
     
    // Create the list items
    m_list.Insert( 0, _T("This") );
    m_list.Insert( 1, _T("That") );
     
    // Associate the list items with the objects
    m_list.SetItemDataPtr(0, m_pLIThis );
    m_list.SetItemDataPtr(1, m_pLIThis );
    Finally, the DoStuff function
    Code:
    CMyDialog::DoStuff()
    {
    	for(int index = 0; index < GetCount(); index++)
    		{
    		CListItemBase* pListItem = 
    		reinterpret_cast<CListItemBase*> m_list.GetItemDataPtr( index );
     
    		ASSERT( NULL != pListItem );
     
    		pListItem->DoStuff();
    	}
    }
    Arjay

  5. #5
    Join Date
    May 2003
    Location
    Corvallis, OR
    Posts
    315

    Thumbs up Re: an alternative to enum{}

    Arjay, that's a really cool idea! I will use the virtual DoStuff fxn to perform explicit tasks for each different type. This eliminates the need for a switch statement.

  6. #6
    Join Date
    May 2003
    Location
    Corvallis, OR
    Posts
    315

    Re: an alternative to enum{}

    Quote Originally Posted by sambo
    This eliminates the need for a switch statement.
    Maybe not completely. It appears that now I will have to use the switch at the time at which I am adding the string (and data) to the list box. ie... I must know which type of class to associate with the item data.

    Code:
    // These objects are declared to have object scope
    // Typically these could be stored in a CTypedPtrList or std::list.
    
    EDIT
    
     //the base
    CListItemBase* m_pLI = NULL; 
    
    //the derived
    CListItemThis* m_pLIThis = NULL;
    CListItemThat* m_pLIThat = NULL;
    CListItemTheOther* m_pLITheOther = NULL;
    
    // create the list item data
    if(type == typeThis)
    {
       CListItemThis m_pLIThis = new CListItemThis();
       m_pLI = (CListItemThis*)m_pLIThis;
    }
    else if(type == typeThat)
    {
       CListItemThat m_pLIThat = new CListItemThat();
       m_pLI = (CListItemThat*)m_pLIThat;
    }
    if(type == typeTheOther)
    {
       CListItemThis m_pLIThis = new CListItemTheOther();
       m_pLI = (CListItemTheOther*)m_pLITheOther;
    }
    else
    {
       ASSERT(false);
       return false;
    }
    
     
    // Create the list item
    m_list.Insert( 0, _T("Could Be Any Derived Type, Or Base Type") );
     
    // Associate the list items with the objects
    if(m_pLI)
    {
       //initialize Base variables   
       m_pLI->m_strAlternateData = strAlternateData; 
    
       m_list.SetItemDataPtr(0, m_pLI );
    }
    Is there a better way to accomplish this task?
    Last edited by sambo; December 28th, 2004 at 04:35 PM.

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: an alternative to enum{}

    Quote Originally Posted by sambo
    I must know which type of class to associate with the item data.
    Not really. Just add the pointer of the derived class to the SetItemDataPtr. When you retrieve it with GetItemDataPtr(), retrieve it as a CListItemBase* pointer and call DoStuff(). Because DoStuff is pure virtual, the appropriate derived class function will get called.

    There's a bug in the previous code, I meant to add m_pLIThat as the 2nd param. Also, notice how I'm storing the derived class pointers rather than the base class pointer.
    Code:
    // Associate the list items with the objects
    m_list.SetItemDataPtr(0, m_pLIThis );
    m_list.SetItemDataPtr(1, m_pLIThat );
    Arjay

  8. #8
    Join Date
    May 2003
    Location
    Corvallis, OR
    Posts
    315

    Re: an alternative to enum{}

    Quote Originally Posted by Arjay
    Not really. Just add the pointer of the derived class to the SetItemDataPtr. When you retrieve it with GetItemDataPtr(), retrieve it as a CListItemBase* pointer and call DoStuff(). Because DoStuff is pure virtual, the appropriate derived class function will get called.
    The list items are not known at run time. And thus, are set according to user interactions. This means that I do not know what type I am dealing with unless I pass a type when the user adds a new item to the list.

    Feel free to set me straight.

  9. #9
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: an alternative to enum{}

    Sure, you'll need to decide what items make up your list whether the user chooses it or you use some other method (like reading the data out of a database). But you use this data only to decide what type of class to create, and once you've done this, you don't really need this info anymore if you are using the base class paradigm.

    Arjay

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured