Inheritance and Data Access Question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bogus1one@yahoo.com

    #1

    Inheritance and Data Access Question

    Let's say I have the following:

    #include <iostream>

    using namespace std;

    class B
    {
    };

    class D1 : public B
    {
    public:
    // Header Functions are the Same
    int Fh1() {return 1;}
    int Fh2() {return 2;}
    int Fh3() {return 3;}

    // Body Functions are Unique
    int Fba() {return 'a';}
    int Fbb() {return 'b';}
    int Fbc() {return 'c';}
    };

    class D2 : public B
    {
    public:
    // Header Functions are the Same
    int Fh1() {return 1;}
    int Fh2() {return 2;}
    int Fh3() {return 3;}

    // Body Functions are Unique
    int Fbx() {return 'x';}
    int Fby() {return 'y';}
    int Fbz() {return 'z';}
    };

    int ParseHeader()
    {
    // What should go here?
    return 0;
    }

    int main(int argc, char* argv[])
    {
    D1 d1;
    D2 d2;

    // Parsing D1 Header
    cout << "Parse D1 Header" << endl;
    ParseHeader();

    // Parsing D1 Body
    cout << "D1 Fba = " << d1.Fba() << endl;
    cout << "D1 Fbb = " << d1.Fbb() << endl;

    // Parsing D2 Header
    cout << "Parse D2 Header" << endl;
    ParseHeader();

    // Parsing D2 Body
    cout << "D2 Fbx = " << d2.Fbx() << endl;
    cout << "D2 Fby = " << d2.Fby() << endl;

    return 0;
    }

    In the above, I can't modify anything in the classes D1 or D2 or B as
    these classes are provided by a 3rd party tool.

    The classes provide data binding for an XML messaging protocol. In
    this protocol, the header for every message will have the same
    structure. You will note above the header functions are the same
    across the two classes Fh1(), Fh2() and Fh3().

    What I would like to do is abstract out the functionality to retrieve
    the header information from the messages as this will be the same
    across all messages. In my example, I show this as the ParseHeader()
    function. I'm looking for suggestions on the best way to accomplish
    this. I tried something with multiple inheritance but I couldn't make
    it work. It smells like there's an elegant way to accomplish this but
    I just can't put my finger on it.

    Thanks.
    Dan


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]

  • Victor Bazarov

    #2
    Re: Inheritance and Data Access Question

    bogus1one@yahoo .com wrote:
    Let's say I have the following:
    >
    #include <iostream>
    >
    using namespace std;
    >
    class B
    {
    };
    >
    class D1 : public B
    {
    public:
    // Header Functions are the Same
    int Fh1() {return 1;}
    int Fh2() {return 2;}
    int Fh3() {return 3;}
    >
    // Body Functions are Unique
    int Fba() {return 'a';}
    int Fbb() {return 'b';}
    int Fbc() {return 'c';}
    };
    >
    class D2 : public B
    {
    public:
    // Header Functions are the Same
    int Fh1() {return 1;}
    int Fh2() {return 2;}
    int Fh3() {return 3;}
    >
    // Body Functions are Unique
    int Fbx() {return 'x';}
    int Fby() {return 'y';}
    int Fbz() {return 'z';}
    };
    >
    int ParseHeader()
    {
    // What should go here?
    return 0;
    }
    template<class D>
    int ParseHeader(D& d)
    {
    cout << d.Fh1() << d.Fh2() << d.Fh3() << endl;
    return 0;
    }
    >
    int main(int argc, char* argv[])
    {
    D1 d1;
    D2 d2;
    >
    // Parsing D1 Header
    cout << "Parse D1 Header" << endl;
    ParseHeader();
    ParseHader(d1);
    >
    // Parsing D1 Body
    cout << "D1 Fba = " << d1.Fba() << endl;
    cout << "D1 Fbb = " << d1.Fbb() << endl;
    >
    // Parsing D2 Header
    cout << "Parse D2 Header" << endl;
    ParseHeader();
    ParseHeader(d2) ;
    >
    // Parsing D2 Body
    cout << "D2 Fbx = " << d2.Fbx() << endl;
    cout << "D2 Fby = " << d2.Fby() << endl;
    >
    return 0;
    }
    >
    In the above, I can't modify anything in the classes D1 or D2 or B as
    these classes are provided by a 3rd party tool.
    >
    The classes provide data binding for an XML messaging protocol. In
    this protocol, the header for every message will have the same
    structure. You will note above the header functions are the same
    across the two classes Fh1(), Fh2() and Fh3().
    >
    What I would like to do is abstract out the functionality to retrieve
    the header information from the messages as this will be the same
    across all messages. In my example, I show this as the ParseHeader()
    function. I'm looking for suggestions on the best way to accomplish
    this. I tried something with multiple inheritance but I couldn't make
    it work. It smells like there's an elegant way to accomplish this but
    I just can't put my finger on it.
    Unless you need a true run-time polymorphism (which you didn't show),
    the templates should work just fine.

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


    Comment

    • Daniel T.

      #3
      Re: Inheritance and Data Access Question

      In article <1163513514.749 864.127550@h54g 2000cwb.googleg roups.com>,
      bogus1one@yahoo .com wrote:
      Let's say I have the following:
      #include <iostream>
      using namespace std;
      class B
      {
      };
      class D1 : public B
      {
      public:
      // Header Functions are the Same
      int Fh1() {return 1;}
      int Fh2() {return 2;}
      int Fh3() {return 3;}
      >
      // Body Functions are Unique
      int Fba() {return 'a';}
      int Fbb() {return 'b';}
      int Fbc() {return 'c';}
      };
      class D2 : public B
      {
      public:
      // Header Functions are the Same
      int Fh1() {return 1;}
      int Fh2() {return 2;}
      int Fh3() {return 3;}
      >
      // Body Functions are Unique
      int Fbx() {return 'x';}
      int Fby() {return 'y';}
      int Fbz() {return 'z';}
      };
      template < typename T >
      int ParseHeader( T& foo)
      {
      foo.Fh1();
      foo.Fh2();
      foo.Fh3();
      return 0;
      }
      int main(int argc, char* argv[])
      {
      D1 d1;
      D2 d2;
      >
      // Parsing D1 Header
      cout << "Parse D1 Header" << endl;
      ParseHeader( d1 );
      // Parsing D1 Body
      cout << "D1 Fba = " << d1.Fba() << endl;
      cout << "D1 Fbb = " << d1.Fbb() << endl;
      >
      // Parsing D2 Header
      cout << "Parse D2 Header" << endl;
      ParseHeader( d2 );
      // Parsing D2 Body
      cout << "D2 Fbx = " << d2.Fbx() << endl;
      cout << "D2 Fby = " << d2.Fby() << endl;
      return 0;
      }
      In the above, I can't modify anything in the classes D1 or D2 or B as
      these classes are provided by a 3rd party tool.
      The classes provide data binding for an XML messaging protocol. In
      this protocol, the header for every message will have the same
      structure. You will note above the header functions are the same
      across the two classes Fh1(), Fh2() and Fh3().
      What I would like to do is abstract out the functionality to retrieve
      the header information from the messages as this will be the same
      across all messages. In my example, I show this as the ParseHeader()
      function. I'm looking for suggestions on the best way to accomplish
      this. I tried something with multiple inheritance but I couldn't make
      it work. It smells like there's an elegant way to accomplish this but
      I just can't put my finger on it.
      --
      To send me email, put "sheltie" in the subject.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • Salt_Peter

        #4
        Re: Inheritance and Data Access Question


        bogus1one@yahoo .com wrote:
        Let's say I have the following:
        >
        #include <iostream>
        >
        using namespace std;
        >
        class B
        {
        };
        >
        class D1 : public B
        {
        public:
        // Header Functions are the Same
        int Fh1() {return 1;}
        int Fh2() {return 2;}
        int Fh3() {return 3;}
        all of these functions should be const.
        ie:
        int Fh1() const { return 1; }
        >
        // Body Functions are Unique
        int Fba() {return 'a';}
        int Fbb() {return 'b';}
        int Fbc() {return 'c';}
        };
        >
        class D2 : public B
        {
        public:
        // Header Functions are the Same
        int Fh1() {return 1;}
        int Fh2() {return 2;}
        int Fh3() {return 3;}
        >
        // Body Functions are Unique
        int Fbx() {return 'x';}
        int Fby() {return 'y';}
        int Fbz() {return 'z';}
        };
        >
        int ParseHeader()
        {
        // What should go here?
        return 0;
        }
        >
        int main(int argc, char* argv[])
        {
        D1 d1;
        D2 d2;
        >
        // Parsing D1 Header
        cout << "Parse D1 Header" << endl;
        ParseHeader();
        >
        // Parsing D1 Body
        cout << "D1 Fba = " << d1.Fba() << endl;
        cout << "D1 Fbb = " << d1.Fbb() << endl;
        >
        // Parsing D2 Header
        cout << "Parse D2 Header" << endl;
        ParseHeader();
        >
        // Parsing D2 Body
        cout << "D2 Fbx = " << d2.Fbx() << endl;
        cout << "D2 Fby = " << d2.Fby() << endl;
        >
        return 0;
        }
        >
        In the above, I can't modify anything in the classes D1 or D2 or B as
        these classes are provided by a 3rd party tool.
        >
        The classes provide data binding for an XML messaging protocol. In
        this protocol, the header for every message will have the same
        structure. You will note above the header functions are the same
        across the two classes Fh1(), Fh2() and Fh3().
        >
        What I would like to do is abstract out the functionality to retrieve
        the header information from the messages as this will be the same
        across all messages. In my example, I show this as the ParseHeader()
        function. I'm looking for suggestions on the best way to accomplish
        this. I tried something with multiple inheritance but I couldn't make
        it work. It smells like there's an elegant way to accomplish this but
        I just can't put my finger on it.
        As it stands, ParseHeader() can only deal with either a D1 object, a D2
        object or both simultaneously. It can't take a reference to B unless B
        has virtual or pure virtual functions.
        Dynamic casting is not an option since B has no virtual functions.
        Instead of abstacting out, you'ld need to abstract in if you plan to
        have ParseHeader accept either a D1 or a D2 object.

        In your particular case, here is what i'ld do (which in effect does
        modify D1 and D2 polymorphicly):

        struct Base
        {
        ~Base() { } // might need to be virtual
        virtual int Fh1() = 0;
        virtual int Fh2() = 0;
        virtual int Fh3() = 0;
        };

        class MyD1 : public D1, public Base
        {
        int Fh1() { return D1::Fh1(); }
        int Fh2() { return D1::Fh2(); }
        int Fh3() { return D1::Fh3(); }
        };

        class MyD2 : public D2, public Base
        {
        int Fh1() { return D2::Fh1(); }
        int Fh2() { return D2::Fh2(); }
        int Fh3() { return D2::Fh3(); }
        };

        int ParseHeader(Bas e& r_b)
        {
        return r_b.Fh1(); // or whatever
        }

        int main()
        {
        MyD1 d1;
        MyD2 d2;

        // Parsing D1 Header
        std::cout << "Parse D1 Header";
        std::cout << ParseHeader(d1) << std::endl;

        // Parsing D2 Header
        std::cout << "Parse D2 Header" << std::endl;
        std::cout << ParseHeader(d2) << std::endl;
        }

        If that doesn't fit the bill, ParseHeader() will need to be implemeted
        twice. Unless, of couse, there is something about B you aren't telling
        us about.


        --
        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • bogus1one@yahoo.com

          #5
          Re: Inheritance and Data Access Question

          How incredibly simple! Thanks to all who replied.
          Dan


          Victor Bazarov wrote:
          bogus1one@yahoo .com wrote:
          Let's say I have the following:

          #include <iostream>

          using namespace std;

          class B
          {
          };

          class D1 : public B
          {
          public:
          // Header Functions are the Same
          int Fh1() {return 1;}
          int Fh2() {return 2;}
          int Fh3() {return 3;}

          // Body Functions are Unique
          int Fba() {return 'a';}
          int Fbb() {return 'b';}
          int Fbc() {return 'c';}
          };

          class D2 : public B
          {
          public:
          // Header Functions are the Same
          int Fh1() {return 1;}
          int Fh2() {return 2;}
          int Fh3() {return 3;}

          // Body Functions are Unique
          int Fbx() {return 'x';}
          int Fby() {return 'y';}
          int Fbz() {return 'z';}
          };

          int ParseHeader()
          {
          // What should go here?
          return 0;
          }
          >
          template<class D>
          int ParseHeader(D& d)
          {
          cout << d.Fh1() << d.Fh2() << d.Fh3() << endl;
          return 0;
          }
          >

          int main(int argc, char* argv[])
          {
          D1 d1;
          D2 d2;

          // Parsing D1 Header
          cout << "Parse D1 Header" << endl;
          ParseHeader();
          >
          ParseHader(d1);
          >

          // Parsing D1 Body
          cout << "D1 Fba = " << d1.Fba() << endl;
          cout << "D1 Fbb = " << d1.Fbb() << endl;

          // Parsing D2 Header
          cout << "Parse D2 Header" << endl;
          ParseHeader();
          >
          ParseHeader(d2) ;
          >

          // Parsing D2 Body
          cout << "D2 Fbx = " << d2.Fbx() << endl;
          cout << "D2 Fby = " << d2.Fby() << endl;

          return 0;
          }

          In the above, I can't modify anything in the classes D1 or D2 or B as
          these classes are provided by a 3rd party tool.

          The classes provide data binding for an XML messaging protocol. In
          this protocol, the header for every message will have the same
          structure. You will note above the header functions are the same
          across the two classes Fh1(), Fh2() and Fh3().

          What I would like to do is abstract out the functionality to retrieve
          the header information from the messages as this will be the same
          across all messages. In my example, I show this as the ParseHeader()
          function. I'm looking for suggestions on the best way to accomplish
          this. I tried something with multiple inheritance but I couldn't make
          it work. It smells like there's an elegant way to accomplish this but
          I just can't put my finger on it.
          >
          Unless you need a true run-time polymorphism (which you didn't show),
          the templates should work just fine.
          >
          V
          --
          Please remove capital 'A's when replying by e-mail
          I do not respond to top-posted replies, please don't ask

          Comment

          Working...