Const is being ignored in virtual function override

118 Views Asked by At

Title kind of says it all. I can't figure out why the compiler will allow this:

#include <iostream>

class Base
{
    public:
    Base() = default;
        virtual ~Base() {}
        virtual void set(const int a) = 0;
};

class Derived : public Base
{
    public:
    Derived() = default;
        virtual ~Derived() {}
    void set(int a) override <-------const tossed out
        {
            a = 2;
            std::cout << "In derived set" << std::endl;
            my_a = a;
        }

    int my_a = 0;
};


int main()
{

        Derived d;
        d.set(4);
}

I understand that functionally, const int a and int a are copies - but why is the const ignored as part of the signature?

The compiler (rightfully) complains about this:

void test1(int a)
{
    a = 2;
}

void test2(const int a)
{
   a = 2; <------ compile error
}

So why does the override pass and basically allow me to do the same thing in the derived class? Why is const not part of the signature for override verification?

Probably a stupid question - but I can't figure out why.

Thanks!

2

There are 2 best solutions below

0
user17732522 On

Top-level const on a function parameter in a function declaration that is not a definition has no meaning at all, just like the name of such a parameter. It is not part of the function's type or signature.

This is so because such a const can only possibly have a meaning for a specific definition. It has no meaning for a caller, for whom declarations are written. At the call site there is no difference in whether or not the function parameter is top-level const.

So

    virtual void set(const int a) = 0;

is 100% equivalent to

    virtual void set(int) = 0;

as it is also for any other function. No matter whether the function parameter is const in the declaration, it can always be or not be top-level const in a definition.

For example:

void f(int); // declaration, not a definition

// definition of the same function with `a` being unmodifiable in the definition
void f(const int a) { }

or:

// declaration, not a definition; `const` ignored
void g(const int); 

// definition of same function with `a` modifiable
void g(int a) { } 

As a consequence, top-level const is also ignored when determining virtual function overrides.

2
memmove On

"In the cpp prime plus 6th edition page744, it says "If you redefined a function in a derived class, it doesn't just override the base class declaration with the same function signature. Instead, it hides all base-class member methods of the same name, regardless of the arugment signatures." When you omit the const keyword, the Derived::set() will hide the Base::set()." That is no good here. Forgive my shallow comprehension of this problem.

As for this statement

void test2(const int a)
{
    a = 2; <------ compile error
}

a will be a const copy of what you passed to this function, means a itself is a const, you can not modify it.