Help with Virtual methods

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

    Help with Virtual methods

    Hi,
    This may be a simple answer for somebody, but I'm unable to figure
    it out. In a nutshell:

    I have a base class defined. Let's call it XClient. Inside XClient I
    have a virtual method called messageHandler, so it looks something
    like this:

    class XClient {
    ......
    public:
    virtual bool messageHandler( .....) = 0;
    };

    I then have a derived class looking something like:

    class XClientWrapper: public XClient{
    public:
    bool messageHandler( ....) = 0;
    };

    I am using this XClientWrapper class in two places in my code. In one
    section I have another class that inheirits XClientWrapper' s
    attributes. Seems to compile and link fine.

    In another section of code I specify an instance of XClientWrapper,
    just a simple:

    XClientWrapper *ptr = new XClientWrapper;

    WHen I compile I get an error stating:
    Cannot allocate an object of type XClientWrapper since the
    following virtual functions are abstract. (messageHandler ).

    If I remove the ' = 0;' from the redefinition of messageHandler in
    XClientWrapper it will compile and link. However, once I do this and
    try to compile my other code that worked fine with the '=0', I get the
    following link error:

    Undefined reference to XClientWrapper virtual table.

    It works one way with the '= 0' and not the other, and vice versa.
    Any ideas?


    Thanks in advance!

    Dennis
  • Ron Natalie

    #2
    Re: Help with Virtual methods


    "Dennis" <dquelch@yahoo. com> wrote in message news:1b936e67.0 308180638.17ea2 f4a@posting.goo gle.com...
    [color=blue]
    >
    > If I remove the ' = 0;' from the redefinition of messageHandler in
    > XClientWrapper it will compile and link. However, once I do this and
    > try to compile my other code that worked fine with the '=0', I get the
    > following link error:
    >
    > Undefined reference to XClientWrapper virtual table.
    >
    > It works one way with the '= 0' and not the other, and vice versa.
    > Any ideas?[/color]

    What exactly are you trying to do? You can not instantiate a function
    with pure virtual functions (= 0 specifier). The pure specifier leaves the
    class abstract. If XClientWrapper is concrete (i.e., no unoverridden
    pure virtual functions), then you must provide the implementation of the
    methods you use.



    Comment

    • Dennis

      #3
      Re: Help with Virtual methods

      Actually, you can even disregard the '=0' from the XClientWrapper.
      That was just the latest iteration I tried to get it to compile and
      link from both sections of code.

      What I had originally started with was not even overridding the
      messageHandler in XClientWrapper and just inheirting it from XClient.
      Again, I would get the same compile and link errors. One section of
      code would compile and link fine without messageHandler defined in
      XClientWrapper, but another section would complain during compilation
      that it couldn't allocate the object since the function messageHandler
      was abstract. If I stuck the definition into XClientWrapper it would
      then compile fine, but the other section of code that use to work
      before would now complain.

      Ideas?

      Dennis


      "Ron Natalie" <ron@sensor.com > wrote in message news:<3f40e621$ 0$144$9a6e19ea@ news.newshostin g.com>...[color=blue]
      > "Dennis" <dquelch@yahoo. com> wrote in message news:1b936e67.0 308180638.17ea2 f4a@posting.goo gle.com...
      >[color=green]
      > >
      > > If I remove the ' = 0;' from the redefinition of messageHandler in
      > > XClientWrapper it will compile and link. However, once I do this and
      > > try to compile my other code that worked fine with the '=0', I get the
      > > following link error:
      > >
      > > Undefined reference to XClientWrapper virtual table.
      > >
      > > It works one way with the '= 0' and not the other, and vice versa.
      > > Any ideas?[/color]
      >
      > What exactly are you trying to do? You can not instantiate a function
      > with pure virtual functions (= 0 specifier). The pure specifier leaves the
      > class abstract. If XClientWrapper is concrete (i.e., no unoverridden
      > pure virtual functions), then you must provide the implementation of the
      > methods you use.[/color]

      Comment

      • John Harrison

        #4
        Re: Help with Virtual methods


        "Dennis" <dquelch@yahoo. com> wrote in message
        news:1b936e67.0 308180850.1c8f9 4bd@posting.goo gle.com...[color=blue]
        > Actually, you can even disregard the '=0' from the XClientWrapper.
        > That was just the latest iteration I tried to get it to compile and
        > link from both sections of code.
        >
        > What I had originally started with was not even overridding the
        > messageHandler in XClientWrapper and just inheirting it from XClient.
        > Again, I would get the same compile and link errors. One section of
        > code would compile and link fine without messageHandler defined in
        > XClientWrapper, but another section would complain during compilation
        > that it couldn't allocate the object since the function messageHandler
        > was abstract. If I stuck the definition into XClientWrapper it would
        > then compile fine, but the other section of code that use to work
        > before would now complain.
        >
        > Ideas?
        >[/color]

        As far as I can tell, what you are failing to do is give a definition for
        XClientWrapper: :messageHandler . That's what the link error is telling you.
        Isn't it obvious? How do you expect your program to work when you don't
        provide a definition for a function?

        john


        Comment

        • Dennis

          #5
          Re: Help with Virtual methods

          The definition is provided at the XClient level and then inheirited to
          XClientWrapper. XClientWrapper can then decide to override it if it
          wants to, which I've decided not to do. What I can't figure out is
          why the linker error is showing up in one instance of the class and
          not another.

          Dennis


          "John Harrison" <john_andronicu s@hotmail.com> wrote in message news:<bhr83d$2e 9tr$1@ID-196037.news.uni-berlin.de>...[color=blue]
          > "Dennis" <dquelch@yahoo. com> wrote in message
          > news:1b936e67.0 308180850.1c8f9 4bd@posting.goo gle.com...[color=green]
          > > Actually, you can even disregard the '=0' from the XClientWrapper.
          > > That was just the latest iteration I tried to get it to compile and
          > > link from both sections of code.
          > >
          > > What I had originally started with was not even overridding the
          > > messageHandler in XClientWrapper and just inheirting it from XClient.
          > > Again, I would get the same compile and link errors. One section of
          > > code would compile and link fine without messageHandler defined in
          > > XClientWrapper, but another section would complain during compilation
          > > that it couldn't allocate the object since the function messageHandler
          > > was abstract. If I stuck the definition into XClientWrapper it would
          > > then compile fine, but the other section of code that use to work
          > > before would now complain.
          > >
          > > Ideas?
          > >[/color]
          >
          > As far as I can tell, what you are failing to do is give a definition for
          > XClientWrapper: :messageHandler . That's what the link error is telling you.
          > Isn't it obvious? How do you expect your program to work when you don't
          > provide a definition for a function?
          >
          > john[/color]

          Comment

          • John Harrison

            #6
            Re: Help with Virtual methods


            "Dennis" <dquelch@yahoo. com> wrote in message
            news:1b936e67.0 308191236.588d4 c3c@posting.goo gle.com...[color=blue]
            > The definition is provided at the XClient level and then inheirited to
            > XClientWrapper. XClientWrapper can then decide to override it if it
            > wants to, which I've decided not to do. What I can't figure out is
            > why the linker error is showing up in one instance of the class and
            > not another.
            >
            > Dennis
            >[/color]

            class XClient {
            ......
            public:
            virtual bool messageHandler( .....) = 0;
            };

            That's looks like a pure virtual function, not a function definition.

            I'm telling you that you haven't defined the function, Ron is telling you
            that you haven't defined the function, the linker is telling you that you
            haven't defined the function. Now maybe there is something you aren't
            telling us, but my money is one the possibility that you misunderstand
            something, and you haven't defined the function.

            john




            Comment

            • Dennis

              #7
              Re: Help with Virtual methods

              John,
              I apologize for my naiveness (is that a word?). This is my first
              experience with virtual functions. Yes, the pure virtual function was
              first defined in XClient. I then inheirited XClient into
              XClientWrapper, which I then want to make use of the messageHandler
              virtual method. You were asking for my definition. I didn't think
              that I needed to define it again explicitly in XClientWrapper but
              could just use it like:

              bool
              XClientWrapper: :messageHandler (....) // argument list the same as
              XClient
              {
              ....code...
              }

              without having to define it explicitly in XClientWrapper class
              (figured it inheirited the definition). I've taken this approach with
              several applications and it has compiled, linked, and run fine.

              However, with this one application that I've run into it's complaining
              about the definition now. Just can't figure out why it worked for one
              and not the other. Is it a compiler fluke that it worked before?

              Thanks for your patience.

              Dennis

              "John Harrison" <john_andronicu s@hotmail.com> wrote in message news:<bhu26r$33 o5l$1@ID-196037.news.uni-berlin.de>...[color=blue]
              > "Dennis" <dquelch@yahoo. com> wrote in message
              > news:1b936e67.0 308191236.588d4 c3c@posting.goo gle.com...[color=green]
              > > The definition is provided at the XClient level and then inheirited to
              > > XClientWrapper. XClientWrapper can then decide to override it if it
              > > wants to, which I've decided not to do. What I can't figure out is
              > > why the linker error is showing up in one instance of the class and
              > > not another.
              > >
              > > Dennis
              > >[/color]
              >
              > class XClient {
              > ......
              > public:
              > virtual bool messageHandler( .....) = 0;
              > };
              >
              > That's looks like a pure virtual function, not a function definition.
              >
              > I'm telling you that you haven't defined the function, Ron is telling you
              > that you haven't defined the function, the linker is telling you that you
              > haven't defined the function. Now maybe there is something you aren't
              > telling us, but my money is one the possibility that you misunderstand
              > something, and you haven't defined the function.
              >
              > john[/color]

              Comment

              • jeffc

                #8
                Re: Help with Virtual methods


                "Dennis" <dquelch@yahoo. com> wrote in message
                news:1b936e67.0 308180850.1c8f9 4bd@posting.goo gle.com...[color=blue]
                > Actually, you can even disregard the '=0' from the XClientWrapper.
                > That was just the latest iteration I tried to get it to compile and
                > link from both sections of code.
                >
                > What I had originally started with was not even overridding the
                > messageHandler in XClientWrapper and just inheirting it from XClient.[/color]

                But that is exactly the same thing. If you don't specify it, it's still
                pure virtual. In a manner of speaking, it's still "=0" until you specify
                otherwise, for all subclasses.


                Comment

                • jeffc

                  #9
                  Re: Help with Virtual methods


                  "Dennis" <dquelch@yahoo. com> wrote in message
                  news:1b936e67.0 308191236.588d4 c3c@posting.goo gle.com...[color=blue]
                  > The definition is provided at the XClient level and then inheirited to
                  > XClientWrapper. XClientWrapper can then decide to override it if it
                  > wants to, which I've decided not to do.[/color]

                  You don't have the option of making that decision. There is nothing wrong
                  with providing a definition of the pure virtual function in the abstract
                  base class (contrary to what many people seem to think.) However, you can
                  NOT aviod explicity defining a function in the base class. In this case,
                  you would simply call the base class. i.e.

                  class XClient {
                  ......
                  public:
                  virtual bool messageHandler( .....) = 0;
                  };

                  class XClientWrapper: public XClient{
                  public:
                  bool messageHandler( ....) = 0;
                  };

                  bool XClientWrapper: :messageHandler (...)
                  {
                  return XClient::messag eHandler(...); // assuming this is actually
                  defined somewhere
                  }


                  Comment

                  Working...