Constructor Behavior

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

    #1

    Constructor Behavior

    Hi.

    I am learning Design Patterns so I pulled this piece of code off the
    ng (decorator) . Now I am going through it with the debugger and
    seeing what does what and I have found something I just don't
    understand.

    The constructor for CCoffeeDecorato r has this in the list
    CCoffeeComponen t().
    > CCoffeeDecorato r( CCoffeeComponen t* pComponent = 0) : CCoffeeComponen t(), m_pComponent( pComponent ) {};
    I see it hitting the CCoffeeComponen t() constructor ... but I can't
    figure out what this accomplishes. The only thing I can think of, is
    that this sets the pointer type to CCoffeeComponen t ... but I don't
    understand the mechanics are behind it.

    Randy



    #include <iostream>
    #include <string>

    using namespace std;

    /*
    *************** *************** *************** *************** *************** *************** *************
    abstract base class ** normal - any class can be decorated.
    hide constructor prevent construction of a plain component
    *
    *************** *************** *************** *************** *************** *************** **************/
    class CCoffeeComponen t {
    public:
    virtual string Info() = 0;

    protected:
    CCoffeeComponen t () {};
    string m_Info;
    };

    /*
    *************** *************** *************** *************** *************** *************** *************
    Furthermore we need a decorator class that "is-a" component and
    stores a
    pointer to a passed component object:
    NOTE: the default NULL-pointer that is used as an end-marker of
    the component chain
    *
    *************** *************** *************** *************** *************** *************** **************/
    class CCoffeeDecorato r : public CCoffeeComponen t {
    public:
    CCoffeeDecorato r( CCoffeeComponen t* pComponent = 0) :
    CCoffeeComponen t(), m_pComponent( pComponent ) {};

    public:
    virtual string Info() {
    if( !m_pComponent )
    return string("");

    return m_pComponent->Info();
    }; // delegate info call to actual
    implementation

    protected:
    CCoffeeComponen t* m_pComponent;

    };

    //This base implementation of the decorator delegates any Info() calls
    to its
    //wrapped component if there is any. In principle we've got the tools
    to
    //create different component combinations at our fingertips. Now we
    get down
    //the some sample component implementations :

    // create different decorator implementations
    class CEspresso: public CCoffeeDecorato r
    {
    public:
    CEspresso( CCoffeeComponen t* pComponent = 0) :
    CCoffeeDecorato r(pComponent ) {};
    // extend info implementation and delegate to base class
    string Info() { return CCoffeeDecorato r::Info() + string("
    espresso"); };
    };

    // create different decorator implementations
    class CSteamedMilk: public CCoffeeDecorato r
    {
    public:
    CSteamedMilk( CCoffeeComponen t* pComponent = 0) :
    CCoffeeDecorato r(pComponent ) {};
    // extend info implementation and delegate to base class
    string Info() { return CCoffeeDecorato r::Info() + string(" steamed
    milk"); };
    };

    // create different decorator implementations
    class CFoamedMilk: public CCoffeeDecorato r
    {
    public:
    CFoamedMilk( CCoffeeComponen t* pComponent = 0) :
    CCoffeeDecorato r(pComponent ) {};
    // extend info implementation and delegate to base class
    string Info() { return CCoffeeDecorato r::Info() + string(" foamed
    milk"); };
    };

    class CSugar: public CCoffeeDecorato r
    {
    public:
    CSugar( CCoffeeComponen t* pComponent = 0) :
    CCoffeeDecorato r( pComponent ){};
    // extend info implementation and delegate to base class
    string Info() { return CCoffeeDecorato r::Info() + string("
    sugar"); };
    };

    class CMug: public CCoffeeDecorato r
    {
    public:
    CMug( CCoffeeComponen t* pComponent = 0) :
    CCoffeeDecorato r( pComponent ){};
    // extend info implementation and delegate to base class
    string Info() {
    return CCoffeeDecorato r::Info() + string(" mug");
    };
    };

    int main()
    {
    /*
    The pointer type is component, however the object type is
    Decorator. This is the
    jist of virtual/polymorphism.

    The recursion here is because the constructor for the decorator is
    */
    CCoffeeComponen t* pCappucino= new CEspresso( new CSugar( new
    CFoamedMilk( new CMug) ) );
    CCoffeeComponen t* pMocca = new CEspresso( new CSugar( new CMug ) );
    CCoffeeComponen t* pEmpty = new CMug;

    cout << "Cappucino components: ";
    cout << pCappucino->Info() << endl;
    cout << "Mocca components: ";
    cout << pMocca->Info() << endl;
    cout << "Empty components: ";
    cout << pEmpty->Info() << endl;

    delete pCappucino;
    delete pMocca;

    system("PAUSE") ;
    return EXIT_SUCCESS;

    return 0;

    }

  • Randy

    #2
    Re: Constructor Behavior


    I don't know how I managed to butcher the English language so bad ...
    Here is what I am actually asking ...

    In the CCoffeeDecorato r constructor list, there is a call to the
    parent class constructor, CCoffeeComponen t(). I can't figure out what
    this accomplishes, in context of this Decorator example.


    Comment

    • Victor Bazarov

      #3
      Re: Constructor Behavior

      Randy wrote:
      I am learning Design Patterns so I pulled this piece of code off the
      ng (decorator) . Now I am going through it with the debugger and
      seeing what does what and I have found something I just don't
      understand.
      >
      The constructor for CCoffeeDecorato r has this in the list
      CCoffeeComponen t().
      >
      >> CCoffeeDecorato r( CCoffeeComponen t* pComponent = 0) :
      >>CCoffeeCompon ent(), m_pComponent( pComponent ) {};
      >
      I see it hitting the CCoffeeComponen t() constructor ... but I can't
      figure out what this accomplishes. The only thing I can think of, is
      that this sets the pointer type to CCoffeeComponen t ... but I don't
      understand the mechanics are behind it.
      Not sure what your confusion is. CCoffeeDecorato r inherits from
      CCoffeeComponen t. The first item in the constructor initialiser list
      is the base class initialiser. It does not have to be there since
      CCoffeeComponen t is a class that can be default-initialised without
      being explicitly mentioned in the initialiser list.

      In reality it accomplishes nothing. You can omit it and the base
      class subobject will still be constructed.
      >
      Randy
      >
      >
      >
      #include <iostream>
      #include <string>
      >
      using namespace std;
      >
      /*
      *************** *************** *************** *************** *************** *************** *************
      abstract base class ** normal - any class can be decorated.
      hide constructor prevent construction of a plain component
      *
      *************** *************** *************** *************** *************** *************** **************/
      class CCoffeeComponen t {
      public:
      virtual string Info() = 0;
      >
      protected:
      CCoffeeComponen t () {};
      string m_Info;
      };
      >
      /*
      *************** *************** *************** *************** *************** *************** *************
      Furthermore we need a decorator class that "is-a" component and
      stores a
      pointer to a passed component object:
      NOTE: the default NULL-pointer that is used as an end-marker of
      the component chain
      *
      *************** *************** *************** *************** *************** *************** **************/
      class CCoffeeDecorato r : public CCoffeeComponen t {
      public:
      CCoffeeDecorato r( CCoffeeComponen t* pComponent = 0) :
      CCoffeeComponen t(), m_pComponent( pComponent ) {};
      >
      public:
      virtual string Info() {
      if( !m_pComponent )
      return string("");
      >
      return m_pComponent->Info();
      }; // delegate info call to actual
      implementation
      >
      protected:
      CCoffeeComponen t* m_pComponent;
      >
      };
      [..]
      V
      --
      Please remove capital 'A's when replying by e-mail
      I do not respond to top-posted replies, please don't ask


      Comment

      • Randy

        #4
        Re: Constructor Behavior


        Thank you Victor

        That was exactly my confusion. As I am new, I just assume that I am
        missing a finer point.

        Randy


        Comment

        • Victor Bazarov

          #5
          Re: Constructor Behavior

          Randy wrote:
          That was exactly my confusion. As I am new, I just assume that I am
          missing a finer point.
          The finer point here *may* be that "everything should be initialised
          or something bad's gonna happen" rule is a good rule to live by. But
          of course the author would know better, and if they didn't explain
          (there or elsewhere in the book), you and I are left to guess...

          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask


          Comment

          • James Kanze

            #6
            Re: Constructor Behavior

            On Sep 12, 4:34 am, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
            Randy wrote:
            That was exactly my confusion. As I am new, I just assume that I am
            missing a finer point.
            The finer point here *may* be that "everything should be initialised
            or something bad's gonna happen" rule is a good rule to live by. But
            of course the author would know better, and if they didn't explain
            (there or elsewhere in the book), you and I are left to guess...
            Let's not forget that the author is providing this code as an
            example. In practice, the base class might not have a default
            constructor (or the default constructor might not be the one we
            want), so his example includes a call to the base class
            constructor. (But I'm not too sure about this. In the
            decorator pattern, the base class will almost surely be an
            interface, whose only constructors are the compiler generated
            default and copy constructors.)

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            Working...