Accessing overridden base methods/functions

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • herlands
    New Member
    • May 2007
    • 3

    Accessing overridden base methods/functions

    Hi!

    Given the following example:
    Code:
    class Base
    {
    public:
    	void doSomething()
    	{
    		//Something...
    	}
    };
    
    class Derived : public Base
    {
    public
    	void doSomething()
    	{
    		// Something else...
    		Base::doSomething();
    	}
    };
    
    int main()
    {
    	Derived d;
    	d.doSomething();
    	return 0;
    }
    Is there any reason why the Base::doSomethi ng() shouldn't be invoked?
  • Darryl
    New Member
    • May 2007
    • 86

    #2
    You forgot a colon after public, but, no, there is no reason why the base dosomething shouldn't be called.

    Comment

    • herlands
      New Member
      • May 2007
      • 3

      #3
      Thank you for your swift reply, Darryl!

      Do you know of any case that would make Base::doSomethi ng invisible when overridden even though it is not a virtual func?

      I am deriving from a precompiled object and the following example works as expected:

      Code:
      class Derived : public Base
      {
      	public:
      	void doSomethingExtra()
      	{
      		//something something...
      		Base::doSomething();
      	}
      };
      But...

      Code:
      class Derived : public Base
      {
      	public:
      	void doSomething()
      	{
      		//something something...
      		Base::doSomething();
      	}
      };
      ...does not! No compiler or runtime error, just no execution of the Base-part.

      Best regards

      Comment

      • Darryl
        New Member
        • May 2007
        • 86

        #4
        I guess it depends on how you are accessing it. For example:

        Code:
        Base* pb = new Derived;
        pb->DoSomething(); // will call the base DoSomething and not the derived;

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Originally posted by herlands
          Do you know of any case that would make Base::doSomethi ng invisible when overridden even though it is not a virtual func?
          Yes. If you have a Derived::doSome thing and you are using a Derived object, the Derived::doSome thing hides, that is dominates, the Base::doSomethi ng(). This is a big no-no becuse you cut out Base behavior in the Derived object. This forces you to call Base::doSomethi ng inside Derived::doSome thing.

          The reason for the no-no is you can't tell inside Derived::doSome thing whether a) you call Base::doSomethi ng first (a pre-condition), b) you call Base::doSomethi ng last ( a post-condition) or c) you do not call Base::doSomethi ng at all. This is a three-way ambiguous scenario.

          Note, this domination is based solely on the function name and does not consider the public/private/protected access specifiers or the function arguments. Example:

          [code=cpp]
          class Base
          {
          public:
          void doSomething()
          {
          //Something...
          }
          };

          class Derived : public Base
          {
          public
          void doSomething(int arg)
          {
          // Something else...
          }
          };

          int main()
          {
          Derived d;
          d.doSomething() ; //ERROR doSomething requires int argument
          return 0;
          }
          [/code]

          Comment

          • Darryl
            New Member
            • May 2007
            • 86

            #6
            The way to "unhide" the base function in your scenario is to use using

            [CODE=cpp]class Base
            {
            public:
            void doSomething(voi d)
            {
            //Something...
            }
            };

            class Derived: public Base
            {
            public:

            using Base::doSomethi ng;

            void doSomething(int arg)
            {
            // Something else...
            }
            };

            int main()

            {
            Derived d;
            d.doSomething() ; //OK now!!!
            return 0;

            }[/CODE]

            Comment

            • herlands
              New Member
              • May 2007
              • 3

              #7
              Hi again :) Thank you both for your replies!

              I have tried to use the [code=c] using Base::doSomethi ng; [/code] but I can't get it to solve the problem. The reason I am deriving this class is that it is a precompiled object that has a lot of calls to it, and I want to add some preconditions ( am I right? ) to the Base functions. In other words the Base functions is used as post-condition in the Derived. I have done this with success several times on other projects, but now it seems to behave differently.

              I solved the problem by renaming all the functions in the Derived and rerouting to the Base class, although I had hoped my inheritance-plan would save me from that kind of work.

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                If I get this right, you just want to change how the base class works. Why not inherit privately?

                Everything in the base class becomes private in the derived class leaving you free to write member functions on the derived class that can to anything you want. Some might just call base class functions, others might do something different, while others may add functionality.

                Private inheritance is implementation inheritance. That is, you want the base class implementation but do not want to expose the base class interface.

                This is a classic way of fixing broken classes that belong to third parties.

                Comment

                • phiefer3
                  New Member
                  • Jun 2007
                  • 67

                  #9
                  Originally posted by weaknessforcats
                  If I get this right, you just want to change how the base class works. Why not inherit privately?

                  Everything in the base class becomes private in the derived class leaving you free to write member functions on the derived class that can to anything you want. Some might just call base class functions, others might do something different, while others may add functionality.

                  Private inheritance is implementation inheritance. That is, you want the base class implementation but do not want to expose the base class interface.

                  This is a classic way of fixing broken classes that belong to third parties.
                  To me it sounded like he wanted to be able to still call the functions as he would fore the base class. for example if he has a base class object and wants it to do something he would do:

                  baseOb.doSometh ing();

                  now he just wants to alter what it does, so he makes a derived class to modify it with conditions so that he can do this:

                  derivedOb.doSom ething();

                  and get the functionality he wants.

                  If he inherits privately he wouldn't be able to call the functions in his program. Basically he just wants to override the function, and also include a call to the base classes version.

                  What if you did something like this:

                  [CODE=cpp]class Base
                  {
                  public:
                  void doSomething()
                  {
                  //Something...
                  }
                  };

                  class Derived : public Base
                  {
                  public:
                  void doSomething()
                  {
                  // Something else...
                  Base *temp = this;
                  temp->doSomething( );
                  }
                  };

                  int main()
                  {
                  Derived d;
                  d.doSomething() ;
                  return 0;
                  }[/CODE]

                  This will create a pointer to the current object that thinks it's a Base object, which will then call the base classes version of the function. I tested it and it seems to work.

                  I think his main problem is that his original post, line 16 attempted to call the function like this: Base::doSomethi ng(); which can't be done unless doSomething() is static. You need to invoke it through an object, and so you just need to treat the current object as a base object to get the base function.

                  Comment

                  • Darryl
                    New Member
                    • May 2007
                    • 86

                    #10
                    What compiler are you using? I just tried this code on MSVC++ 2005 and it works as expected:
                    [CODE=cpp]include <iostream>

                    class base
                    {
                    public:
                    void doSomething()
                    {
                    std::cout << "Base\n";
                    }
                    };

                    class derived : public base
                    {
                    public:
                    void doSomething()
                    {
                    base::doSomethi ng();
                    std::cout << "Derived\n" ;
                    }
                    };
                    int main()
                    {
                    derived b;
                    b.doSomething() ;
                    }[/CODE]

                    Comment

                    • phiefer3
                      New Member
                      • Jun 2007
                      • 67

                      #11
                      Originally posted by Darryl
                      What compiler are you using? I just tried this code on MSVC++ 2005 and it works as expected:
                      [CODE=cpp]include <iostream>

                      class base
                      {
                      public:
                      void doSomething()
                      {
                      std::cout << "Base\n";
                      }
                      };

                      class derived : public base
                      {
                      public:
                      void doSomething()
                      {
                      base::doSomethi ng();
                      std::cout << "Derived\n" ;
                      }
                      };
                      int main()
                      {
                      derived b;
                      b.doSomething() ;
                      }[/CODE]
                      yeah, I didn't even try the original, but I did now, and it does work. But if it is a compiler problem, making a base class pointer to the current object to call the base class function should get around any compiler specific problems.

                      Comment

                      Working...