Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: call pure virtual function from member function of same class

Consider the following 2 programs.

#include <iostream>
using std::cout;
class Base {
    public:
        virtual void f()=0;
        void g() {
            f();
        }
        virtual ~Base() { }
};
class Derived : public Base
{
    public:
    void f() {
        cout<<"Derived::f() is called\n";
    }
     ~Derived() {}
};
class Derived1 : public Base
{
    public:
    void f() {
        cout<<"Derived1::f() is called\n";
    }
    ~Derived1() { }
};
int main() {
    Derived1 d;
    Base& b=d;
    b.g();
    b.f();
}

Compiles & runs fine and gives expected outcome..

#include <iostream>
using std::cout;
class Base {
    public:
        virtual void f()=0;
        Base() {
            f();    // oops,error can't call from ctor & dtor
        }
};
class Derived : public Base
{
    public:
        void f() {
            std::cout<<"Derived::f() is called\n";
        }
};
int main() { Derived d; Base& b=d; b.f(); }

The above program fails in compilation. Why is it allowed to call a pure virtual function from the member function of the same class in which the pure virtual function is declared? Is it fine to do this or is it undefined behavior because derived class still doesn't provide an implementation of the pure virtual function? Why can't a pure virtual function be called from constructor & destructor of the same class? I know that Derived class constructors can call pure virtual functions of the base class. What does the C++ standard say about this?

like image 814
Destructor Avatar asked May 23 '15 17:05

Destructor


People also ask

Is it possible to call a pure virtual function?

You may call a virtual function as long as it is not a pure virtual function, and as long as you know that what you are calling is the method from the class itself and not expecting any polymorphism. Calling a pure virtual function from a constructor is undefined behaviour even if it has an implementation.

Can you call a pure virtual function in base class?

In our discussion __purecall , we saw that you can declare a pure virtual function with the = 0 syntax, and if you try to call one of these functions from the base class, you will get the dreaded R6025 – pure virtual function call error.

Why we use pure virtual function in CPP?

A pure virtual function is a virtual function in C++ for which we need not to write any function definition and only we have to declare it. It is declared by assigning 0 in the declaration. An abstract class is a class in C++ which have at least one pure virtual function.

Which is used to create a pure virtual function Mcq?

Which is used to create a pure virtual function? d) ! Explanation: For making a method as pure virtual function, We have to append '=0' to the class or method.


Video Answer


2 Answers

"Why pure virtual function can't be called from constructor ... ?"

Because the final class isn't constructed completely at this point, and the vtable isn't completely setup, to dispatch the function call correctly.


You may alternatively use a static relationship for base and derived class like proposed with the CRTP:

template<class DerivedType>
class Base {
    public:
        void g() {
            static_cast<DerivedType*>(this)->f();
        }
        virtual ~Base() { }
};

class Derived : public Base<Derived>
{
    public:
    void f() {
        cout<<"Derived::f() is called\n";
    }
     ~Derived() {}
};

class Derived1 : public Base<Derived1>
{
    public:
    void f() {
        cout<<"Derived1::f() is called\n";
    }
    ~Derived1() { }
};
like image 137
πάντα ῥεῖ Avatar answered Sep 20 '22 14:09

πάντα ῥεῖ


Why it is allowed to call pure virtual function from the member function of same class in which pure virtual function is declared?

Because this is technically feasible and used in practice: see the Template Method pattern.

Why pure virtual function can't be called from constructor & destructor of the same class?

This is technically not straight-forward to implement in C++ (no vtable yet). But more fundamentally, you should not need it anyway since you always know the exact class of your object when calling a constructor.

like image 23
Bérenger Avatar answered Sep 21 '22 14:09

Bérenger