Virtual Func Problem
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Virtual Func Problem

  1. #1
    Join Date
    Sep 1999
    Location
    USA - NJ
    Posts
    3

    Virtual Func Problem

    Why does this code not compile?
    If I declare a function in a derived class of the same name as a virtual function in a base class - yet the new function has different parameters...
    I can't call the base class version of that function?
    Code Below:
    ====

    #include "stdafx.h"
    #include <conio.h>
    #include <ctype.h>

    class foo
    {
    public:
    virtual void funcA(){printf("foo\n");};
    };

    class bar : public foo
    {
    public:
    virtual void funcA(char a){printf("bar\n");};
    };

    int main(int argc, char* argv[])
    {
    printf("Hello C++!\n");
    bar obj;
    obj.funcA('a');
    obj.funcA(); //error C2660: 'funcA' : function does not take 0 parameters WHY??

    printf("Press Any Key To End!\n");
    getch();
    return 0;
    }





  2. #2
    Join Date
    Jun 1999
    Location
    Miami, FL
    Posts
    972

    Re: Virtual Func Problem

    This is a C++ behavior which I don't particularly like. A function in derived class hides ALL functions in its base class with the same name, even if the parameters are different. So if you want to make the base class's functions available in the derived class you need to redefine them, sort of like this:

    virtual void funcA() { foo::funcA(); }



    If you don't want to do that, you can still access the base function explictly, like this:

    obj.foo::funcA();



    However, this doesn't look as clean as calling the function directly.

    Believe it or not, there are good reasons for this unexpected "function hiding" behavior. I don't quite remember them but I think it has to do with making it safer when you're working with deep class hierarchies.

    Cheers!
    Alvaro


  3. #3
    Join Date
    May 1999
    Posts
    69

    Re: Virtual Func Problem

    Because the presence of a virtual function declared in the derived class hides the base class function.


  4. #4
    Join Date
    Sep 1999
    Posts
    2

    Re: Virtual Func Problem

    The overridden function in the derived class should not be virtual. If not then the base class will be called.


  5. #5
    Join Date
    Sep 1999
    Location
    USA - NJ
    Posts
    3

    Re: Virtual Func Problem

    Thanks...!
    After your explination I see in the Annotated C++ Reference I see what you're talking about.
    (Section 13.1 - Declaration Matching)

    I guess I see the point of the whole thing...

    If I have a function like CMyClass::Initialize() that effects the state of the entrie class...I want to make **** sure that the derived version(s) of that function gets called. If my base class version is called I could be half-initialized...
    If I could call any version of Initialize() from any base class...it would never be clear which function was safe...

    sigh...wish I could control that behavior... oh well...copy and paste is fun...


  6. #6
    Join Date
    Sep 1999
    Posts
    13

    Re: Virtual Func Problem

    Mike:

    I often make use of a function to initialize the data members of any classes I define, I typically call it InitDataMembers, to avoid the cut and paste I simply call the base class init function at the start of my derived class init function. This results in having the base class init its members, and my derived class then inits any members unique to it. If I derive yet another class from the derived class, it too starts by initializing its base class (which, in turn is derived from the original base class).

    Personally I find this approach to be clean, and understandable.

    Have fun,

    Jim




  7. #7
    Join Date
    Sep 1999
    Location
    NJ
    Posts
    1,299

    Re: Virtual Func Problem

    In reply to:

    If I have a function like CMyClass::Initialize() that effects the state of the entrie class...I want to make **** sure that the derived version(s) of that function gets called. If my base class version is called I could be half-initialized...
    If I could call any version of Initialize() from any base class...it would never be clear which function was safe...





    That is precisely the case for which this feature was added. Consider the class

    class Base
    {
    Initialize();
    // etc
    };

    class Derived1: public Base
    {
    // no Initialize()
    };

    class Derived2: public Base
    {
    Initialize(int nNeededData);
    };

    Derived1 d1;
    Derived2 d2;

    d1.Initialize(); // OK
    d2.Initialize(); // ERROR



    Note that the second case is an error, which is EXACTLY what you want it to be.



    Truth,
    James

  8. #8
    Join Date
    Sep 1999
    Location
    USA - NJ
    Posts
    3

    Re: Virtual Func Problem

    Well, What I'm taking about is a little different then your example...
    Try this...


    class CMyBase
    {
    public:
    virtual void Initialize(int iSomeValue)
    {
    m_iBaseVal = iSomeValue;
    };

    public:
    int m_iBaseVal;
    };

    ////////////////////////////////////////

    class CMyDerived : public CMyBase
    {
    public:
    virtual void Initialize(int iSomeValue, int iSomeOtherVal)
    {
    CMyBase::Initialize(iSomeValue);
    m_iDerivedVal = iSomeOtherVal;
    };

    public:
    int m_iDerivedVal;
    };

    ////////////////////////////////////////

    int main(int argc, char* argv[])
    {
    CMyDerived obj;
    obj.Initialize(10,20);//ok

    obj.Initialize(10); //ERROR!: (C2660)
    //if this was allowed m_iDerivedVal wouldn't be "initialize()-ed" correctly
    //but the user of the class would have no way of knowing which version
    //of initialize() was valid. Thats why is not visible...
    //HOWEVER - I can force the issue like below...
    obj.CMyBase::Initialize(10); //this works...but CMyDerived was never "initialize()-ed"

    return 0;
    }




    If Initialize(int iSomeValue) is OK for CMyDerived then it must be implimented in that class - it cannot be inherited.

    The point is that once you override one version of a virtual function you no longer inherite ANY other version of that function. I completely understand now why this is a good thing...


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center