Madhav Bajaj
Madhav Bajaj

Reputation: 21

Virtual Functions in Derived Classes

I have been watching several videos, and I have come to know how virtual function calls are processed through late binding.

In early binding, for lines like ptr->func(...), the compiler reviews the data type for ptr and looks in the corresponding class for the func(...) definition.

While during late binding for virtual functions, ptr address is accessed, and then the definition is looked up in the corresponding class.

If I am right about the mechanism I have just mentioned, then why does the following code produce an error?

class A{
   public:
       void func(){
       }
};

class B: public A{
    public:
       virtual void f4(){
           cout<<"Cunt"<<endl;
       }

};

int main(){
    A* ptr;
    B obj;
    ptr=&obj;
    ptr->f4();
    return 0;
}

Also, why does the below code produce the output base instead of the output derived?

class A{
   public:
       void f4(){
           cout<<"base"<<endl;
       }
};

class B: public A{
    public:
       virtual void f4(){
           cout<<"derived"<<endl;
       }

};

int main(){
    A* ptr;
    B obj;
    ptr=&obj;
    ptr->f4();
    return 0;
}

Please help. Am I wrong about the mechanism?

Upvotes: 2

Views: 58

Answers (2)

Coral Kashri
Coral Kashri

Reputation: 3506

In class A, the function f4 should be defined as virtual too:

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

In your case, f4 is non-virtual function, due to non-virtual inheritance.
One more thing, derived virtual functions should be mark as override, and the virtual is not necessary:

class B : public A {
public:
    void f4() override {
        std::cout << "derived" << std::endl;
    }
};

If you would try to mark f4 in B as override without making it virtual in A first, you would get the compilation error: error: ‘virtual void B::f4()’ marked ‘override’, but does not override- which means that you won't be able to access it using A class pointer.

Side note: read the following post: Why is "using namespace std;" considered bad practice?

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 595402

In your first example, A does not have a method named f4(), so the call to ptr->f4() is not valid.

In your second example, A::f4() is not marked as virtual, so the call to ptr->f4() does not perform virtual dispatch, and so calls A::f4() rather than B::f4().

The solution to both problems is the same - make f4() be virtual in A, and have B override it, eg:

class A{
   public:
       virtual void f4() {
           cout << "base" << endl;
       }
};

class B: public A{
    public:
       void f4() override {
           cout << "derived" << endl;
       }
};

int main(){
    A* ptr;
    B obj;
    ptr = &obj;
    ptr->f4();
    return 0;
}

Upvotes: 1

Related Questions