A C++ program puzzle

  Peter        2012-05-13 02:31:26       11,567        4    

Recently I came across a question asked by wang2191195 on a Chinese IT forum CSDN which asks about a C++ program puzzle. He has a code snippet which cannot be compiled. The code is:
#include <cstdlib>
#include <iostream>


using namespace std;

class Base{

public:

    virtual void func(){
        cout << "Base::func()" << endl;
    }

    virtual int func( int num ){
        cout << "Base::func( int " << num << " )" << endl;
        return 0;
    }

};

class Derived : public Base{

public:

    virtual void func(){
        cout << "Derived::func()" << endl;
    }

};

int main(){
    
    Derived d;
    d.func();
    d.func(1);
    system("PAUSE");
}
The compile result is :
D:\Projects\C++\tmp\tmp\test.cpp: In ‘int main()
D:\Projects\C++\tmp\tmp\test.cpp:36:10: error:The call to ‘Derived::func(int)’ has no matched function
D:\Projects\C++\tmp\tmp\test.cpp:36:10: The alternative is
D:\Projects\C++\tmp\tmp\test.cpp:26:15: virtual void Derived::func()
D:\Projects\C++\tmp\tmp\test.cpp:26:15: The alternative function requires 0 parameter, 1 is provided

He doesn't know why this compilation error occurs. He used virtual in the base class, he should be able to call the base class's
int func( int num )
method, but unfortunately, it is not working.

The reason for this compilation error is that in C++ standard 2003, there is a statement says:

3.3.7 Name hiding [basic.scope.hiding]
1 A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived
class (10.2).

So here in the derived class, the
void func()
method overrides the method in the Base class and it also hides the base class's method with 1 parameter which is
int func( int num )
here even if you use virtual in Base class, it's no use for the Derived class.

Then some people ask whether this is a C++ bug or not because they think if they don't override the base class's method, they should be able to use it in derived classes, this is more logical. But in C++ standards, it says this conforms to the standard. I don't know why the designers choose this design.

Do you have any idea why C++ designer design this feature?

Reference:http://topic.csdn.net/u/20120508/10/2935efc4-3289-4309-a903-46e16ed16449.html


C++  OVERLOAD  PUZZLE  HIDE 

       

  RELATED


  4 COMMENTS


Stefano [Reply]@ 2012-05-14 08:43:32
Even more weird (at least, if you do not know what's happening), if you had a default argument for "num" in the base class and you overrided it in the derived, the default argument the compiler uses is the one in the base class.
fu [Reply]@ 2012-05-14 09:28:23
You are missing an "using Base::func;" statement inside derived class
Dale [Reply]@ 2012-05-14 09:48:21
The overload resolution rules are already complicated. Allowing for overload resolution between functions in the derived class and functions in the base classes is going to create a set of rules that are difficult to implement correctly and test, and nearly impossible to understand. In a situation like the one above, there is no function in the derived class that is acceptable, so it would make sense to search the base class. However, when you get into situations where you have multiple candidate functions in the derived class and multiple base classes, you need rules for resolving the conflict. Those rules could be written, but as a developer, I'm sure that they would cause frequent confusion. This more brute force rule serves as a message that you shouldn't do that.
robdesbois [Reply]@ 2012-05-23 03:20:46
More explanation on the rationale behind the name hiding rule is in this discussion: https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c++.moderated/6v-FP5VnXfs [My email address rob.desbois@gmail.com gets rejected by the comment posting script, which replies "Not an emailNot an email" o_O]


  RANDOM FUN

Merge conflict in real time