Virtual Functions in C++ and Java

邮差的信 提交于 2019-12-21 17:52:30

问题


I have been reading about Virtual functions and found,

VF are used in polymorphism of an inherited class.

So , if a class and derived class both have the same function name, VF binds the appropriate function to the function call.

i.e. If the function in question is designated virtual in the base class then the derived class's function would be called. If it is not virtual, the base class's function would be called.

In Java by default: all functions are Virtual C++: Non-virtual and can be made Virtual in Java by using final, private access modifier while in C++ using Virtual keyword to make a function virtual.

Based on the above theory, i wrote the code:

#include <iostream>

class base{
    public : 
        virtual void function1(){
            std::cout<<"BaseVirtual"<<std::endl;
        }

        void function2(){
            std::cout<<"Base NonVirtual"<<std::endl;
        }
};


class derieved: public base
{
    public : 
        void function1(){
            std::cout<<"Derieved Virtual"<<std::endl;
        }

        void function2(){
            std::cout<<"Derieved NonVirtual"<<std::endl;
        }
};



int main()
{
    base b1;
    derieved d1;

    b1.function1();
    b1.function2();

    d1.function1();
    d1.function2();    

}

Now based on the fact, if its a virtual function then only derived class function is called, my output for the above program should be:

BaseVirtual
Base NonVirtual
Derieved Virtual
Base NonVirtual

however, it came out to be:

BaseVirtual
Base NonVirtual
Derieved Virtual
Derieved NonVirtual

which must be right of course. So my question is the output totally violates the statement If the function in question is designated virtual in the base class then the derived class's function would be called. If it is not virtual, the base class's function would be called. for the call:

  d1.function2();    

回答1:


Yes.. the role of virtual comes into picture if and only if you have are trying to access the derived class object with a base class pointer.

With you example:-

#include <iostream>

class base{
    public : 
        virtual void function1(){
            std::cout<<"BaseVirtual"<<std::endl;
        }

        void function2(){
            std::cout<<"Base NonVirtual"<<std::endl;
        }
};


class derieved: public base
{
    public : 
        void function1(){
            std::cout<<"Derieved Virtual"<<std::endl;
        }

        void function2(){
            std::cout<<"Derieved NonVirtual"<<std::endl;
        }
};



int main()
{
    base *b1;
    derieved d1;

    b1=&d1;

    b1->function1();
    b1->function2();    
    return 0;
}

output:-

Derieved Virtual
Base NonVirtual



回答2:


Right now, you're creating one object each of base and derived, and then invoking function1 and function2 directly on those objects. Under these conditions, virtual (or lack thereof) makes no difference at all.

At least in C++, for virtual to mean anything, you need to be working with a pointer (or reference) to a base class that's referring to an object that may be either the base or the derived class:

base *b2 = &d1;

// invoke non-virtual function. Inovkes base::function1, because we're using 
// pointer to base.
b2->function1(); 

// invoke virtual function. Invokes derived::function2 because the pointee object
// is a derived.
b2->function2();

This is particularly useful if you have (for example) a collection of pointers to objects, where those the objects those pointers refer to may be any of several different types. One of the classic examples is a base shape class, with line, circle, square, etc. derived from it. When you invoke the draw member of each, each draws its own shape. In this particular case, your base class is probably an abstract base class -- the draw member is declared "pure virtual", meaning you can't create an object of the base shape class, and to create an instance of a derived class, that has to override the draw member function:

class shape {
public:
    virtual void draw() = 0;
};

class circle : public shape { 
public:
    virtual void draw() { /* draw itself */ }
};

Then, in your drawing program, you have a collection of (pointers to) shapes the user has created, and to draw them all, you just walk through the collection and tell each to draw itself. The higher level code doesn't need to know or care whether a particular shape is a circle, square, triangle, etc.

for (int i=0; i<shapes.size(); i++)
    shapes[i]->draw();



回答3:


Polymorphism in C++ requires utilizing pointers. If you change your example to:

base *b1 = new base();
base *d1 = new derived();

This will actually utilize the virtual mechanism. However, you seem to be confused with the basic ideas behind polymorphism. If you define a class as derived, of course it will call functions defined in the derived class, and likewise with base.

Edit: To make this more explicit, here's the output and an explanation:

b1->function1(); //Will call base::function1()
b1->function2(); //Will call base::function2()
d1->function1(); //Will call derived::function1()
d2->function2(); //Will call derived::function2()

All polymorphism/virtual calls do is allow you to treat a derived pointer as a base type, while calling the (correct) derived functions on it. So if you had another function such as:

void foo(base& b)
{
    b.function1();
}

Then passing b1 will call base::function1(), passing d1 will call derived::function1().



来源:https://stackoverflow.com/questions/13023028/virtual-functions-in-c-and-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!