7

I am trying to override the size function in Vector_container but the IDE is telling me "Non-virtual member function marked 'override' hides virtual member function"

class Container {
public:
    virtual double& operator[](int) = 0;     // pure virtual function
    virtual int size() const = 0;            // const member function (§4.2.1)
    virtual ~Container() {}                  // destructor (§4.2.2)
};


class Vector_container : public Container {   // Vector_container implements Container
public:
    Vector_container(int s) : v(s) { }   // Vector of s elements
    ~Vector_container() {}

    double& operator[](int i) override { return v[i]; }
    int size() override { return v.size(); }
private:
    Vector v;
};

But isn't it a virtual function?

Paul Renton
  • 2,652
  • 6
  • 25
  • 38
Lester
  • 357
  • 3
  • 16
  • 5
    The virtual function in the base class is different. It is const – A M Dec 07 '19 at 16:41
  • 2
    Functions are overloadable by being marked `const`. – George Dec 07 '19 at 16:41
  • 3
    Unrelated: `size()` functions for a container should probably return `size_t` instead of `int`. – ChrisMM Dec 07 '19 at 16:45
  • So annoying. The compiler correctly identifies an issue and comes up with a warning (and apparently warnings are treated as errors), but the warning is so darn useless as to confuse the user. How much extra would it cost to output `int size() hides int size() **const**` with the warning just so the unaware user doesn't waste half an hour wondering what's wrong? – Damon Dec 07 '19 at 17:18
  • I am using XCode, sir. – Lester Dec 07 '19 at 17:27
  • Adding a link to a similar question which goes more in depth about const and function signatures. Hope this helps – Paul Renton Mar 18 '20 at 04:41

2 Answers2

3

Constness is important here. Your Container declares a purely virtual int size() const, while you attempt to override int size(). Declaring your override as const works according to my tests.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • if I change it to int size() const override { return v.size(); } it tells me "'this' argument to member function 'size' has type 'const Vector', but function is not marked const" – Lester Dec 07 '19 at 16:43
  • 1
    @Lester If you wrote `Vector::size`, then you should probably mark that `const` as well. – George Dec 07 '19 at 16:45
  • Wow. Thank you for checking for me. No telling what is going on here! :) – Lester Dec 07 '19 at 16:46
  • @Lester No problem and @George Thanks for that note; my test assumed that `Vector` had a const size since I stubbed it out with std::vector. – nanofarad Dec 07 '19 at 16:50
1

As others mentioned, the use of const changes the signature of the function. I want to add a couple more tidbits of knowledge that will help others in the future.

When overriding a function in C++ and if your compiler supports C++11 and onward, use the override keyword at the end of your function signature. This will yield more helpful information from the compiler. The compiler can then cause the program to fail at compile time if the virtual function had an override keyword. The error would occur if the compiler cannot find a parent virtual function with the same function signature to override. It is almost always better to catch mistakes at compile time as opposed to run-time.

It appears as if you did the override keyword, so it likely pointed you in the right direction. The main reason I am belaboring this point is I want others who see this question to realize that you can catch mistaken overrides with that keyword at compile time.

A common practice people do in industry is to provide an a base function with and without const. While many may say this defeats the purpose of const, there are several cases where you may need to call a const function on a non-const function or non-const object. The only other alternative is using mutable, which I find less C++ programmers understand the meaning.

In short, const changes the signature of the function and therefore can only be overridden on a child class if the const signature matches.

Here is a link to a similar question, which goes more in depth about const and function signatures. It also delves into Mutable and bitwise const vs conceptual const. Hope this helps your understanding - c++ function syntax/prototype - data type after brackets

Paul Renton
  • 2,652
  • 6
  • 25
  • 38