Thread: casting to void pointers dynamically

  1. #1
    dp_goose
    Guest

    Question casting to void pointers dynamically

    I have this example below to help explain things

    -------------------------------
    #include <stdio.h>

    class CItem
    {
    public:
    void PrintMsg(const char *Msg);
    };

    void CItem::PrintMsg(const char *Msg)
    {
    printf("%s\n",Msg);
    }

    class CList
    {
    public:

    void *Head;

    CList();
    ~CList();
    void Add();
    };

    CList::CList()
    {
    Head=NULL;
    }

    CList::~CList()
    {
    if(Head!=NULL)
    delete Head;
    }

    void CList::Add()
    {
    Head=new CItem;
    Head->PrintMsg("Testing.1.2.3");
    }

    void main()
    {
    CList aList;
    aList.Add();

    }
    ----------------------------------------
    I will have several different types of CItem objects ie. CItemTypeA, CItemTypeB (not derived but objects in their own right) but want only one CList to handle them.

    The above listing is a very basic example of want I want to do but I can't work out how to get the CList::Add function working because of the Head is not a class/struct/union in the line Head->PrintMsg. The only way I have managed to get it working is to have a large macro that containg the whole of the list CList class to make different versions.

    Is there a way of testing for the type of an object so I could have different versions of the Head pointer for the different CItem objects and use a switch to select the correct one. I'm guessing this would get complicated but I can't think of/get working any other method. I have looked into dynamic_cast, RUNTIME_CLASS etc but got very confused and I'm not using MFC so this rules out the RUNTIME_CLASS macro anyway.

    I hope this makes sense to someone out there.

    Thanks

    Goose

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    1) Code tags.
    2) You can't delete a void pointer to an object and have it properly work. It won't call the destructor of the class properly. Here's an example:

    Code:
    #include <iostream>
    
    class CMyClass{
    public:
    	CMyClass(){
    		std::cout << "  Constructor" << std::endl;
    	}
    	~CMyClass(){
    		std::cout << "  Destructor" << std::endl;
    	}
    };
    
    int main(){
    	std::cout << "First pointer:" << std::endl;
    	CMyClass * p = new CMyClass();
    	delete p;
    	std::cout << "Second pointer:" << std::endl;
    	void * p2 = new CMyClass();
    	delete p2;
    	std::cout << "End." << std::endl;
    }
    yields:

    Code:
    First pointer:
      Constructor
      Destructor
    Second pointer:
      Constructor
    End.
    If you need to have multiple types represented by a single pointer, create a base class (with its destructor virtual) and make the pointer a pointer to the base class. E.g.:

    Code:
    #include <iostream>
    
    class CBase{
    public:
    	CBase(){
    		std::cout << "  Base Constructor" << std::endl;
    	}
    	virtual ~CBase(){
    		std::cout << "  Base Destructor" << std::endl;
    	}
    };
    
    class CDerived : public CBase{
    public:
    	CDerived(){
    		std::cout << "  Derived Constructor" << std::endl;
    	}
    	~CDerived(){
    		std::cout << "  Derived Destructor" << std::endl;
    	}
    };
    
    
    int main(){
    	std::cout << "First pointer:" << std::endl;
    	CDerived * p = new CDerived();
    	delete p;
    	std::cout << "Second pointer:" << std::endl;
    	CBase * p2 = new CDerived();
    	delete p2;
    	std::cout << "End." << std::endl;
    }
    yields:

    Code:
    First pointer:
      Base Constructor
      Derived Constructor
      Derived Destructor
      Base Destructor
    Second pointer:
      Base Constructor
      Derived Constructor
      Derived Destructor
      Base Destructor
    End.
    Of course, you can make the base constructors/destructors empty; E.g., your base class can be as simple as:

    Code:
    class CBase{
    public:
    	virtual ~CBase(){}
    };
    All you really need is to tell the compiler that the destructor is virtual; in this way, deleting a CBase * will properly delete pointer to objects derived from CBase.
    Last edited by Cat; 07-18-2003 at 11:59 AM.

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    161

    Re: casting to void pointers dynamically

    Originally posted by dp_goose
    The only way I have managed to get it working is to have a large macro that containg the whole of the list CList class to make different versions.
    This type of programming can be accomplished using C++ templates.


    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template<typename T>
      class MyClass
      {
      public:
        MyClass(T t): value(t) {}
        T& getValue() { return value; }
    
      private:
        T value;
      };
    
    int main()
    {
      MyClass<int> my_int_class(50);
      MyClass<string> my_string_class(string("testing"));
    
      cout << my_int_class.getValue() << endl;
      cout << my_string_class.getValue() << endl;
    
      return 0;
    }

  4. #4
    dp_goose
    Guest

    Thumbs up I've use the templates idea

    I used the template idea and it works a treat.

    Thanks

    Goose

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 05-13-2007, 08:55 AM
  2. ChangeDisplaySettings - Blank?
    By Tonto in forum Windows Programming
    Replies: 13
    Last Post: 12-26-2006, 04:17 PM
  3. Pls repair my basketball program
    By death_messiah12 in forum C++ Programming
    Replies: 10
    Last Post: 12-11-2006, 05:15 AM
  4. i cannot see the mouse arrow
    By peachchentao in forum C Programming
    Replies: 6
    Last Post: 12-10-2006, 04:14 AM
  5. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM