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)   
|