home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,776 of 33,346   
   Kelvin Chung to All   
   Creating type erasure   
   05 Jan 12 09:04:31   
   
   From: kelvSYC@mac.com   
      
   Suppose I have a class Base and three derived classes, Derived1,   
   Derived2, and Derived3.  Suppose I also have this thing:   
      
   class Result {   
   	boost::shared_ptr ptr;	// This will always be a Derived1 or   
   a   
   Derived2 pointer, never Derived3   
   public:   
   	int getProperty();   
   };   
      
   The value returned from getProperty() can be determined at compile-time   
   (ie. all Derived1 return the same value and all Derived2 return the   
   same value) - the limitation of Result::ptr to Derived1 or Derived2   
   pointers is that this property is not well-defined for Derived3.  The   
   question I have is in implementing getProperty().   
      
   Suppose I have this class:   
      
   template    
   class DerivedProperty;   
      
   template<>   
   class DerivedProperty : public boost::integral_constant   
   {};   
      
   template<>   
   class DerivedProperty : public boost::integral_constant   
   {};   
      
   (BTW, How do you ensure that DerivedProperty is never instantiated with   
   Derived3 due to its not-well-definedness, Base due to its   
   incompleteness, or any unrelated class due to its unrelatedness?)   
      
   As Result::ptr will always be a Derived1 or a Derived2 pointer,   
   getProperty() should return DerivedProperty::value or   
   DerivedProperty::value, where appropriate.  Except that   
   Result doesn't have any information on which subclass the pointer   
   should be.   
      
   >From reading about how you can do type erasure in C++, I think I should   
   do something like this:   
      
   class Result {   
   	struct ResultBase {   
   		virtual boost::shared_ptr getPtr() = 0;		//   
   In case the ptr   
   from before is needed elsewhere   
   		virtual int getProperty() = 0;   
   	};   
   	   
   	template    
   	struct ResultModel : public ResultBase {   
   		// Has a constructor that takes in the pointer, virtual   
   destructor, etc.   
   		boost::shared_ptr ptr;   
   		boost::shared_ptr getPtr() { return ptr; }   
   		int getProperty() { return DerivedProperty::value;   
   }   
   	};   
   public:   
   	template    
   	Result(const boost::shared_ptr& ptr) : impl(new   
   ResultModel(ptr));   
   	   
   	int getProperty() { return impl.getProperty(); }   
   private:   
   	boost::shared_ptr impl;   
   };   
      
   I believe that should be the proper way to do what I have described,   
   which retains enough flexibility that I can, say, later define a   
   Derived4 with a well-defined DerivedProperty, and not have to modify   
   Result.  Is this true, and what other things should I be aware of if it   
   is?   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca