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

Discussion in 'C++' started by Teis Draiby, Apr 2, 2004.

  1. Teis Draiby

    Teis Draiby Guest

    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 createSubClassInstance(void);
    };


    class mySubClass: public myMainClass
    {
    };

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


    I'm am looking forward for your clever answer
    regards, Teis
     
    Teis Draiby, Apr 2, 2004
    #1
    1. Advertising

  2. On Fri, 02 Apr 2004 12:41:56 +0200, Teis Draiby wrote:

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


    Why? Ideally the base class shouldn't need to know about the derived
    class(es)

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


    With a class declaration like this:

    class mySubClass;

    > class myMainClass
    > {
    > public:


    /* you did say you wanted it to return a pointer */
    mySybClass *createSubClassInstance(void)

    > };
    >
    >
    > class mySubClass: public myMainClass
    > {
    > };



    --
    NPV

    "the large print giveth, and the small print taketh away"
    Tom Waits - Step right up
     
    Nils Petter Vaskinn, Apr 2, 2004
    #2
    1. Advertising

  3. Teis Draiby

    Teis Draiby Guest

    > Why? Ideally the base class shouldn't need to know about the derived
    > class(es)


    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(char *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:fileReader> 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
     
    Teis Draiby, Apr 2, 2004
    #3
  4. Teis Draiby

    Pete Vidler Guest

    Teis Draiby wrote:
    > 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.


    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_ptr, replace the above with:
    // template< class T >
    // boost::shared_ptr< 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::Derivation ) { ... }

    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_ptr,
    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
     
    Pete Vidler, Apr 2, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. tirath
    Replies:
    3
    Views:
    726
    Ivan Vecerina
    Oct 12, 2003
  2. Kavya
    Replies:
    2
    Views:
    397
  3. Replies:
    1
    Views:
    411
    myork
    May 23, 2007
  4. Replies:
    1
    Views:
    399
    Victor Bazarov
    May 23, 2007
  5. , India
    Replies:
    8
    Views:
    999
    gwowen
    Aug 18, 2010
Loading...

Share This Page