简体   繁体   中英

function overriding in c++

could anyone explain function overriding in c++ please! also am confused about virtual function concept. some tutorials say without the keyword virtual, both the derived class and base class objects invoke the base class function. then how does overriding take place?

There's no need to redocument what is already good and out there. I think this and this are a wonderful explanations about virtual functions. Then you probably also need to hear about abstract classes. Let us know if you have further questions.

Read this please. Concentrate on C++ sections. Then ask specific questions you have after reading.

Let me try to post an example (This is out of my head, so there may be slight syntax errors :) )

Baseclass:

class BaseClass
{
public:
   void normalFunction();
   virtual void virtualFunction();
}

Derived class:

class DerivedClass : public BaseClass
{
public:
   void normalFunction();
   virtual void virtualFunction();
}

Okay, so we got our classes defined. Now, some examples:

void main()
{
    BaseClass base;
    DerivedClass derived;

    base.normalFunction();   //Invokes BaseClass::normalFunction();
    base.virtualFunction();  //Invoked BaseClass::virtualFunction();

    derived.normalFunction();//Invokes DerivedClass::normalFunction();
    derived.virtualFunction();//Invokes DerivedClass::virtualFunction();

    // Okay, nothing special yet, here comes the fun:
    BaseClass *basePtr = &base;
    BaseClass *derivedPtr = &derived;

    basePtr->normalFunction(); //Invokes BaseClass::normalFunction();
    basePtr->virtualFunction();//Invokes BaseClass::virtualFunction();

    derivedPtr->normalFunction(); //Invokes BaseClass::normalFunction(); !! this is because it's a BaseClass pointer.
    derivedPtr->virtualFunction();//Invokes DerivedClass::virtualFunction();
}

.. So, in conclusion, without virtual, the type of the pointer dictates which method will be invoked, with virtual, any type overriding the virtual method will have it's method called regardless of the pointer type :)

This is at a cose of a very minor overhead in the form of a vtable (virtual table), a compiler-detail which will map each method to the different derived types.

Each C++ class that has at least one virtual function contains a "virtual table" or VTABLE which is used to dynamically look up the address of a function at runtime.

Suppose you have two classes: Base and Derived. Further suppose that Derived derives from Base, and that "b" and "d" are instances of Derived, but b's compile-time type is Base and d's is Derived.

Now suppose that both Base and Derived declare a function "foo". Now, if "foo" is declared to be virtual in Base, then "foo" will have an entry in Base's VTABLE, and when you call "b.foo()" or "d.foo()", the compiler will know that it is a virtual function, and it will inject code that will look up the address of "foo" in the VTABLE at runtime.... which will find the address of the definition of "foo" as given in class Derived (ie Derived::foo).

Now suppose that both Base and Derived declare a function "foo", but "foo" has not been declared virtual in Base. When you call "b.foo()" or "d."foo()" the compiler will attempt to call Base::foo and Derived::foo directly, bypassing the virtual table lookup. Even though b's runtime type may be Derived, b's compile-time type is Base, and so calling "b.foo()" will result in "Base::foo" rather than "Derived::foo" being called.

In C++, the term "overriding" is used to refer to the former case; that is, when the function is declared as virtual, and another function in a derived class replaces the original function that was defined in the base class. By contrast, the term "overshadowing" is used to refer to the latter case; that is, a function in the derived class is called instead of the one in the base class, simply because it is closer in scope, but it has not truly replaced the function that was defined in the base class.

The override can only be done if you declare the function in the super virtual. Because it is virtual so it's not true ... meaning that is someone invoke it with that signature it may not invoke that function. We have to wait and see at runtime if someone overridden it. That is the meaning of virtual.

class A {
            void F_A() { cout << "A' A"; }
    virtual void F_B() { cout << "A' B"; }
}
class B : public A {
    void F_B() { cout << "B' B"; }
}

A o = new B();
o.F_A();  // Non-virtual so the compiler knows that it can only be the one in class A
o.F_B();  // Virtual so the compiler does not know if at runtime ... o is instance of A or B. So it have to wait and see.
// In this case, it's B at runtime ('`new B()`'), so it run the one in B.

To sum up, if a function (method to be more precise) is declared ' virtual' , it can be overridden. Otherwise, it can't be; hence, any invocation always goes to the one in the super class.

Hope this help clarifying.

For Virtual function always remember this thumb rule :

  • When function is normal then function of type of object will be invoked,
  • When function is Virtual then function of type of actual instance will be called.

I like to illustrate this example with a Chess board;

class ChessPiece
{
    public:
        void moveTo(Pos dst);
        virtual checkValidAndMoveTo(Pos dst) = 0;
};
class King: public ChessPieve
{        virtual checkValidAndMoveTo(Pos dst);}
class Queen: public ChessPieve
{        virtual checkValidAndMoveTo(Pos dst);}
// etc

ChessPiece*   board[8][8];

So when a move is made to square the game will call checkValidAndMoveTo() on the piece.

board[pickedUpPiece.x][pickedUpPiece.y]->checkValidAndMoveTo()

This will now call the appropriate checkValidAndMoveTo() for the particular piece. Once this move is finished we expect it to call MoveTo(). Since at the point it knows what type is is it will drill to down and get the most overidden version of MoveTo() below it current type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM