Base class method that returns a pointer to a derived class?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Teis Draiby

    Base class method that returns a pointer to a derived class?

    I want to write a base class that includes a member function that creates an
    instance of a derrived class and returns a pointer to it.

    Problem: The derived class definition has to follow the base class
    definition. Therefore I can't specify the return type of the function, that
    returns a pointer to the derived class, because the derived class is not yet
    known at that point.
    Hov can I solve this problem? In a nice manner :)



    -- Source Code ------------------------------------------------

    class myMainClass
    {
    public:
    mySubClass createSubClassI nstance(void);
    };


    class mySubClass: public myMainClass
    {
    };

    ----------------------------------------------------------------------


    I'm am looking forward for your clever answer
    regards, Teis


  • Nils Petter Vaskinn

    #2
    Re: Base class method that returns a pointer to a derived class?

    On Fri, 02 Apr 2004 12:41:56 +0200, Teis Draiby wrote:
    [color=blue]
    > I want to write a base class that includes a member function that creates an
    > instance of a derrived class and returns a pointer to it.[/color]

    Why? Ideally the base class shouldn't need to know about the derived
    class(es)
    [color=blue]
    > Problem: The derived class definition has to follow the base class
    > definition. Therefore I can't specify the return type of the function, that
    > returns a pointer to the derived class, because the derived class is not yet
    > known at that point.
    > Hov can I solve this problem? In a nice manner :)[/color]

    With a class declaration like this:

    class mySubClass;
    [color=blue]
    > class myMainClass
    > {
    > public:[/color]

    /* you did say you wanted it to return a pointer */
    mySybClass *createSubClass Instance(void)
    [color=blue]
    > };
    >
    >
    > class mySubClass: public myMainClass
    > {
    > };[/color]


    --
    NPV

    "the large print giveth, and the small print taketh away"
    Tom Waits - Step right up

    Comment

    • Teis Draiby

      #3
      Re: Base class method that returns a pointer to a derived class?

      > Why? Ideally the base class shouldn't need to know about the derived[color=blue]
      > class(es)[/color]

      Maybe you're right, but here's the reason (don't read it - it is not
      important):

      It's for a console window in a Win32 application.
      The base class creates the console window and has methods like
      'putMessage(cha r *message)'.

      Different classes or other logical sections of my program should have the
      option to create its own message class instance. These instances output to
      the same console window and don't want to initialize any new console
      windows. The main reason is to put a prefix to each message indicating who
      send the message:

      // the message class instance is created as the first thing:
      myApp> Welcome to myApp!
      // later the fileReader class makes its own instance:
      myApp:fileReade r> File "myFile.xml " loaded succesfully!

      thus I want the base class to create these instances. Since the instances
      would do almost the same as the base class except initializing the window
      they are implemented as a derived class. It will contain additional methods
      like toggleOnOff().

      Maybe it's a better idea to make both classes as derrived classes of a new
      base class.

      regards, Teis




      Comment

      • Pete Vidler

        #4
        Re: Base class method that returns a pointer to a derived class?

        Teis Draiby wrote:[color=blue]
        > I want to write a base class that includes a member function that creates an
        > instance of a derrived class and returns a pointer to it.[/color]

        I posted a very similar problem to the moderated newsgroup and got an
        excellent reply. Firstly, it's best to note that the abstract factory
        pattern might be more appropriate for what you want (I don't know your
        situation). It's something to look into.

        This is the trick, originally posted to the moderated group by Maxim
        Yegorushkin (altered a little by me):

        class Base
        {
        public:
        Base( Derivation ) { ... }

        template< class T >
        T Create() { return T( Derivation() ); }

        // To return a boost::shared_p tr, replace the above with:
        // template< class T >
        // boost::shared_p tr< T > Create() { return new T( Derivation ); }

        protected:
        Base() { ... }
        struct Derivation {};

        private:
        // You might want copy ctors and copy assignment operators here.
        };

        class Derived : public Base
        {
        public:
        Derived( Base::Derivatio n ) { ... }

        protected:
        Derived() { ... }
        };

        Derived can now only be created like this:

        Derived d = Base::Create< Derived >();

        Any other attempt to create it will cause a compiler error. It works
        because the constructor that is used by Create is public, but cannot be
        accessed outside the hierarchy because the parameter is a protected
        member of Base.

        Issues:

        1) Two constructors required per class. This is not strictly true, but
        if you don't provide a protected default constructor, the public
        constructor must pass its parameter back to its base class' constructor.

        2) If you leave out the public constructor in a class, but keep the
        protected default constructor, you will have a class that cannot be
        created (but classes derived from it can still be created). This is
        useful when you want this functionality but can't provide a pure virtual
        method.

        3) Think carefully about what you want to return from Create. As it
        stands the object is returned by value (which means the copy-constructor
        and copy assignment operator can still be used to construct a new
        object). This might be fine for you, but if not you can either make them
        private or return a smart pointer instead (such as boost::shared_p tr,
        from www.boost.org).

        I will say this once more -- you would do well to look into abstract
        factory and other design patterns/techniques before using this. Your
        choice, though.

        Oh, and I don't guarantee that the above code compiles, obviously. :)

        -- Pete

        Comment

        Working...