3

For example:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    void go() { };
};

Implicit overriding of function go can be undesirable, because it is not recognizable that B::go() is hiding or overriding the same function of struct A or even it may be a new function that does not exist in struct A. override feature of C++11 is useful when you want a desirable overriding of virtual functions, but in my case it is undesirable and i didn't want to override function go(), that means if i knew there was a virtual function I wouldn't override it in struct B.

What i want is something similar to [[check_names]] attribute proposal that didn't approve to C++11. Does C++ have a language feature for it?

By the way, do compilers (such as GCC and VC++) have an option to show a warning (a warning is enough if error is not available!) if an implicit overriding of a virtual function happens? if they have, can you provide an example for GCC?

EDIT: I am not talking about force or a language feature, all i want is a warning or anything that allow me to recognize the undesirable overriding.

EDIT: What can be a desirable overriding? it can be something like the following code:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    virtual void go() { };
};

or:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    void go() override { };
};

or something similar by using an attribute.

Sadeq
  • 7,795
  • 4
  • 34
  • 45
  • 5
    Do you want to disallow overriding in all base classes? If so, use `final`. – juanchopanza Jul 28 '14 at 16:13
  • Function hiding isn't a bug, its a feature :-P – IdeaHat Jul 28 '14 at 16:22
  • 1
    @Nasser this is not a dupe of that Q. Here, the question is to detect overriding at the class definition. – Walter Jul 28 '14 at 16:27
  • @Walter, if you look at the question I linked, it states: "how can one determine at run-time whether a non-pure virtual function (with an implementation in the base class) has been re-implemented in the derived class?". – Nasser Al-Shawwa Jul 28 '14 at 16:33
  • @Hsi-HungShih: That question is related to mine, but i am not talking about force or a language feature, all i want is a warning or anything that allow me to recognize the undesirable overriding. BTW in that question, no answer solved it, the accepted answer was only a mention of a dropped proposal. – Sadeq Jul 28 '14 at 16:44
  • If you don't want to allow overloading at all, why not just make the method non-virtual? – aruisdante Jul 28 '14 at 16:53
  • 1
    @ccsadegh no answer solved it because for now there seems no way to solve it until the compilers implement it. If you look at G++, Visual Studio, and clang warning lists, there are no such warning flags. – Hsi-Hung Shih Jul 28 '14 at 16:54
  • Have you looked at static analysis tools other than compilers? – Ben Voigt Jul 28 '14 at 17:00
  • @BenVoigt: no, what are they? can they do the job? which tools? – Sadeq Jul 28 '14 at 17:02
  • It would help a bit if you explained why you want to do what you are doing. Are you trying to detect if some class down the hierarchy accidentally overrides a method in the base class without realizing that's what they are doing? – aruisdante Jul 28 '14 at 17:04
  • @ccsadegh: There are a variety, one example is Gimpel PC Lint. Google for "C++ static checker". The accepted answer in the linked question on enforcing overrides mentions some `achecker` in the comments. – Ben Voigt Jul 28 '14 at 17:04
  • @aruisdante: http://en.wikipedia.org/wiki/Fragile_base_class – Ben Voigt Jul 28 '14 at 17:05
  • 1
    @BenVoigt right, but there are certainly language features that completely disable overloading (make it non-virtual, or mark it ``final`` somewhere in the chain). It seems like the OP is looking for something different, where a user of the class is warned if they're overloading a 'fragile' method unless they somehow declare they know what they are doing. – aruisdante Jul 28 '14 at 17:07
  • @aruisdante: You're looking at this from the opposite perspective from the brittle base class problem. What if the author of the base class adds a new virtual member that happens to have the same signature as a member in a derived class? Action-at-a-distance, although the derived class source code has not changed, its member has become an overrider. – Ben Voigt Jul 28 '14 at 17:10
  • @aruisdante: absolutely that is what i want :D – Sadeq Jul 28 '14 at 17:11
  • @BenVoigt that's absolutely true. But why I say we need OP clarification. It's hard to tell if they're worried about a change to ``A`` breaking ``A`` because of ``B`` or a change to ``B`` breaking ``A``/``B`` because of ``A``. – aruisdante Jul 28 '14 at 17:11
  • @aruisdante: He's pretty clear -- he wants a warning if an function is an overrider and isn't explicitly marked as such. Which is exactly what the "enforce override keyword" question asks as well. Hence a duplicate. – Ben Voigt Jul 28 '14 at 17:13
  • @BenVoigt: no, that question is different. no enforce and no need for a standard C++ feature. – Sadeq Jul 28 '14 at 17:18
  • @ccsadegh: That question says "(i.e. if I forget to say `override`, then I want to get a warning/error.)" Doesn't seem different to me. – Ben Voigt Jul 28 '14 at 17:32
  • @Nasser precisely: *at run-time*, but this question is concerned with *compile-time* AFAI understand it. – Walter Jul 29 '14 at 17:39

1 Answers1

1

I guess you can use tagging,

#include <iostream>
#include <memory>

using namespace std;

struct no_override_tag
{};

struct A
{
    virtual void go() { cout <<"A::go" << endl;};
};

struct B : public A
{
    void go(no_override_tag={}) { cout << "B::go" <<endl; };
};

int main()
{
    unique_ptr<A> upA(new B);
    upA->go(); // no override, calls `A::go()` instead of `B::go()`


}

Basically you add a default-initialized argument of a type no_override_tag as the last argument in B::go(), and this will make the signature of B::go different, no matter what you declaration you have in A. Not super elegant but it works, however I don't know why would you really want to do this.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • The problem is that overriding is undesirable, that means i even don't know that i am going to override a function or not. – Sadeq Jul 28 '14 at 16:51
  • @ccsadegh then add the tag to the signature, and you'll be sure the function won't override anything. You cannot force the compiler to emit a warning though, no matter what. – vsoftco Jul 28 '14 at 16:53
  • 3
    If this method is used, he has to add this no_override_tag to every method that is not intended to override anything. – Hsi-Hung Shih Jul 28 '14 at 16:57
  • 1
    @Hsi-HungShih which sounds like it defeats the purpose, in that it sounds like the OP is trying to detect *accidental* overloading, where some child class way down the class hierarchy doesn't realize there is a method called ``go()`` in the parent class and redefines it. – aruisdante Jul 28 '14 at 17:03
  • 1
    Then maybe the "opposite" could help: `void A::go(override_tag={})` ? – alain Jul 28 '14 at 17:07
  • @aruisdante, I missed his point I guess, but if the reverse then alain's proposal sounds ok. – vsoftco Jul 28 '14 at 17:33