Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

covariant virtual function in C++

Tags:

c++

I tried following program, but compiler shows error.

#include <iostream>
class Base
{
    public:
        virtual Base& fun() const 
        {
            std::cout<<"fun() in Base\n";
            return *this;
        }
};
class Derived : public Base
{
    public:
         Derived& fun() const
        {
            std::cout<<"fun() in Derived\n";
            return *this;
        }
};
int main()
{
    Base* p=new Derived();
    p->fun();
    delete p;
    return 0;
}

Compiler errors:

[Error] invalid initialization of reference of type 'Base&' from expression of type 'const Base'
[Error] invalid initialization of reference of type 'Derived&' from expression of type 'const Derived'

Why I am getting these errors?
But when I write following in both class' function program works fine.

return (Base&)*this;      // write this line in Base class function
return (Derived&)*this    // write this line in Derived class function

What is the meaning of above 2 statements?
Please help me.

like image 628
Destructor Avatar asked Dec 12 '22 05:12

Destructor


1 Answers

Solution:

In your fun member functions (i.e., for both Base::fun and Derived::fun) you have to either drop the const qualifier of the function:

virtual Base& fun() 
{
  std::cout<<"fun() in Base\n";
  return *this;
}

or return a const reference to a Base class object.

virtual const Base& fun() const
{
  std::cout<<"fun() in Base\n";
  return *this;
}

Live Demo

Also you have to define a virtual destructor at least for your Base class to ensure that destructors are evoked in the correct order.

Explanation:

According to the standard § 9.3.2 The this pointer [class.this]:

In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*. [ Note: thus in a const member function, the object for which the function is called is accessed through a const access path. — end note ]

Thus, interpreting the above, in a const member function this is const so returning it as non-const reference drops its const qualifier and therefore the compiler rightfully complains.

like image 143
101010 Avatar answered Dec 21 '22 02:12

101010