Virtual Funtion Questions

Discussion in 'C++' started by garyolsen, Dec 2, 2003.

  1. garyolsen

    garyolsen Guest

    Case 1:
    ==============

    class MyClass
    {
    public:
    virtual void MyVirt();
    };

    class MyChildClass : public MyClass
    {
    public:
    void MyVirt();
    };

    If MyClass contains a virtual function which will be overridden by it
    children classes:

    MyChildClass *MChildC = new MyChildClass();
    MyClass* ptr = MChildC;
    ptr->MyVirt();//MyChildClass::MyVirt() called

    Otherwise, the overriding function, MyVirt(), in MyChildClass will not be
    executed?

    Everything fine. Please read on...


    Case 2:
    =============

    The same two classes as in Case 1.

    MyChildClass MCC;
    MyClass* ptr = &MCC;
    ptr->MyVirt();

    Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?
    Is this a general practice of polymorphism in C++ like in Case 1?

    Now, this leads me to another question:

    Why such a "Pointer"/"Reference" requirement needed to cause a late binding?


    Case 3:
    ==============

    Now we make some changes for the above two classes:

    class MyClass
    {
    public:
    void MyNonVirt() { MyVirt(); }

    private:
    virtual void MyVirt();
    };

    class MyChildClass : public MyClass
    {
    private:
    void MyVirt();
    };

    Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.

    First, is this a good design at all?

    How should I do to make sue that MyChildClass::MyVirt() is called at
    runtime?


    Thanks!
    garyolsen, Dec 2, 2003
    #1
    1. Advertising

  2. garyolsen

    Ron Natalie Guest

    "garyolsen" <> wrote in message news:Ft6zb.141759$...

    >
    > Why such a "Pointer"/"Reference" requirement needed to cause a late binding?


    The only way you can get to a an object whose dynamic type is different from
    the static type is to use (at least implcitly) a pointer or reference.

    MCC.MyVirt(); // no brainer, MCC is of type MyChildClass
    ptr->MyVirt(); // must figure out dymaic type of *ptr at runtime
    >


    >
    > Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.


    Protection doesn't have any bearing on virtual. You can't call MyVirt() from
    outside MyClass if it's private (makes no different if virtual or not)>

    > How should I do to make sue that MyChildClass::MyVirt() is called at


    It will be called if you call MyNonVirt() in the context of a MyChildClass object.


    The way function calling works is like this:

    1. First for the static type of the call, the name is looked up. If you call through
    a pointer of type MyClass, then it finds MyCLass::MyNonFirst.
    2. Possible overloads are checked (you only have the one).
    3. Access is checked (OK, public).
    4. If virtual, the final overrider is substituted (it's not).

    Ok, now you're executing MyNonVirt. You go through the process again:

    1. Lookup Name: Find MyClass::MyVirt
    2. Check overloads (only one).
    3. Check access (fine, private but being called from within class)
    4. If virtual, substitute final overrider (yes, it's virtual, object is of type MyChildClass so My ChildClass::MyVirt is run).
    Ron Natalie, Dec 2, 2003
    #2
    1. Advertising

  3. "garyolsen" <> wrote...
    > Case 1:
    > ==============
    >
    > class MyClass
    > {
    > public:
    > virtual void MyVirt();
    > };
    >
    > class MyChildClass : public MyClass
    > {
    > public:
    > void MyVirt();
    > };
    >
    > If MyClass contains a virtual function which will be overridden by it
    > children classes:
    >
    > MyChildClass *MChildC = new MyChildClass();
    > MyClass* ptr = MChildC;
    > ptr->MyVirt();//MyChildClass::MyVirt() called
    >
    > Otherwise, the overriding function, MyVirt(), in MyChildClass will not be
    > executed?


    Yes. If the function is not virtual, there is no "overriding" of it,
    the MyChildClass' function with the same name would _hide_ the MyClass'
    one.

    >
    > Everything fine. Please read on...
    >
    >
    > Case 2:
    > =============
    >
    > The same two classes as in Case 1.
    >
    > MyChildClass MCC;
    > MyClass* ptr = &MCC;
    > ptr->MyVirt();
    >
    > Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?


    Of course. What's the difference with the above, really? That
    the object was created in freestore instead of automatically? It
    makes no difference.

    > Is this a general practice of polymorphism in C++ like in Case 1?


    Similar.

    > Now, this leads me to another question:
    >
    > Why such a "Pointer"/"Reference" requirement needed to cause a late

    binding?

    Because without it (by value) the _slicing_ occurs, and there is no
    original object left.

    > Case 3:
    > ==============
    >
    > Now we make some changes for the above two classes:
    >
    > class MyClass
    > {
    > public:
    > void MyNonVirt() { MyVirt(); }
    >
    > private:
    > virtual void MyVirt();
    > };
    >
    > class MyChildClass : public MyClass
    > {
    > private:
    > void MyVirt();
    > };
    >
    > Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.
    >
    > First, is this a good design at all?


    It's _a_ design. There has to be a purpose to it. If such design
    exists, there must have been a purpose. Don't ask us to guess it.

    > How should I do to make sue that MyChildClass::MyVirt() is called at
    > runtime?


    The same way. If your pointer to MyClass is a pointer to a _subobject_
    of an object of MyChildClass, then calling MyNonVirt for it will cause
    the internal call to MyVirt to be dispatched _dynamically_. So, no
    special action necessary.

    Victor
    Victor Bazarov, Dec 2, 2003
    #3
  4. garyolsen

    jeffc Guest

    "garyolsen" <> wrote in message
    news:Ft6zb.141759$...
    >
    > Case 2:
    > =============
    >
    > The same two classes as in Case 1.
    >
    > MyChildClass MCC;
    > MyClass* ptr = &MCC;
    > ptr->MyVirt();
    >
    > Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?
    > Is this a general practice of polymorphism in C++ like in Case 1?


    Yes, it might not be done exactly that way - it might be a parameter on a
    function call, but the idea is the same.

    > Why such a "Pointer"/"Reference" requirement needed to cause a late

    binding?

    Because there's isn't an alternative. How else would you cause late
    binding?

    > Case 3:
    > ==============
    >
    > Now we make some changes for the above two classes:
    >
    > class MyClass
    > {
    > public:
    > void MyNonVirt() { MyVirt(); }
    >
    > private:
    > virtual void MyVirt();
    > };
    >
    > class MyChildClass : public MyClass
    > {
    > private:
    > void MyVirt();
    > };
    >
    > Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.
    >
    > First, is this a good design at all?


    It looks OK to me, depending on what you need to accomplish.

    > How should I do to make sue that MyChildClass::MyVirt() is called at
    > runtime?


    As you have it written, it will be - assuming an object of type MyChildClass
    such as
    MyClass* pClass = new MyChildClass;
    pClass->MyNonVirt();
    jeffc, Dec 2, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sam Holden

    Re: fraction reducing funtion

    Sam Holden, Aug 3, 2003, in forum: C++
    Replies:
    2
    Views:
    350
    Sam Holden
    Aug 4, 2003
  2. Guest
    Replies:
    6
    Views:
    2,665
    Siemel Naran
    Jul 15, 2004
  3. derrick
    Replies:
    1
    Views:
    349
    Mike Wahler
    Dec 22, 2004
  4. JS
    Replies:
    6
    Views:
    304
    Default User
    Mar 15, 2005
  5. Lee Xuzhang
    Replies:
    5
    Views:
    315
    Kevin D. Quitt
    Jun 14, 2006
Loading...

Share This Page