CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Construction from abstract base pointer

    I have a "BaseAbstractClass", and three derived classes, "ClassA", "ClassB" and "ClassC".

    All three of my classes A,B and C can be constructed from another class. ie, for class a, I have:

    Code:
        ClassA(ClassA& i);
        ClassA(ClassB& i);
        ClassA(ClassC& i);
    but not ClassA(ClassBase& i);

    I would like to know how to construct an object of class ClassA, from a pointer to BaseClass, which could be any of ClassA, B or C?

    This doesn't work, kind of obviously...

    Code:
    //pb is of type BaseClass*
    ClassA aObj(*pB);
    error is no matching function for call to `ClassA::ClassA(ClassBase&)'

    I guess I should write a ClassA(ClassBase* ip), but I'm unsure how to implement that.

  2. #2
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Construction from abstract base pointer

    I would do something like this:
    Code:
    class ClassA;
    
    class ClassBase {
    public:
      virtual ClassA constructClassA() = 0;
    }
    
    class ClassA : public ClassBase {
    public:
      virtual ClassA constructClassA() { return ClassA(*this); }
    }
    
    class ClassB : public ClassBase {
    public:
      virtual ClassA constructClassA() { return ClassA(*this); }
    }
    
    class ClassC : public ClassBase {
    public:
      virtual classA constructClassA() { return ClassA(*this); }
    }
    
    ClassA aObj = pB->constructClassA();
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  3. #3
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: Construction from abstract base pointer

    Maybe you can use the visitor pattern to create an instance of Class A?

    Code:
    struct IAbstractVisitor
    {
       virtual IAbstractVisitor()
       {
       }
    
       virtual void accept( ClassA& op ) = 0;
       virtual void accept( ClassB& op ) = 0;
       virtual void accept( ClassC& op ) = 0;
    };
    
    struct BaseClass
    {
       virtual void visit( IAbstractVisitor& visitor ) = 0;
    };
    
    struct ClassA
    {
       void visit( IAbstractVisitor& visitor )
       {
          visitor.accept( *this );
       }
    };
    
    struct ClassB
    {
       void visit( IAbstractVisitor& visitor )
       {
          visitor.accept( *this );
       }
    };
    
    struct ClassB
    {
       void visit( IAbstractVisitor& visitor )
       {
          visitor.accept( *this );
       }
    };
    
    struct ClassACreator : public IAbstractVisitor
    {
       ClassA instance_;
    
       void visit( ClassA& op )
       {
          // invoke copy constructor with arg type ClassA
          instance_ = ClassA( op );
       }
    
       void visit( ClassB& op )
       {
          // invoke copy constructor with arg type ClassB
          instance_ = ClassA( op );
       }
    
       void visit( ClassC& op )
       {
          // invoke copy constructor with arg type ClassC
          instance_ = ClassA( op );
       }
    };
    
    ClassA makeClassA( BaseClass& base )
    {
       ClassACreator  Creator;
    
       base.accept( base );
    
      return Creator.instance_;
    }
    There are one and a half major drawbacks in this approach:
    1) you have to modify BaseClass, ClassA, ClassB and ClassC
    2) calling makeClassA includes two copy constructor calls. I only count this half a drawback because the compiler might do some optimizations. It can be removed completely by returning pointers to the ABC instead of objects.

    A templated creator class removes duplicate code:

    Code:
    template<typename T>
    struct ClassCreator
    {
       T instance_;
    
       ClassCreator( BaseClass& base )
       {
          base.accept( *this );
       }
    
       void visit( ClassA& op )
       {
          // construct from ClassA
          instance_ = T( op );
       }
    
       void visit( ClassB& op )
       {
          // construct from ClassB
          instance_ = T( op );
       }
    
       void visit( ClassC& op )
       {
          // construct from ClassC
          instance_ = T( op );
       }
    };
    
    template<typename T>
    T make( BaseClass& base )
    {
       return ClassCreator<T>( base ).instance_;
    }
    Edit:
    I found an possibly unwanted behaviour when using my code: Since make returns an object by value one additional call to the copy constructor of the same type will be made. I don&#180;t know if this issue renders the whole thing useless.
    Last edited by GNiewerth; July 14th, 2009 at 07:04 AM.
    - Guido

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