C++的疑似BUG?解决思路

C++的疑似BUG?
C/C++ code

#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");
}



此代码编译不通过
D:\Projects\C++\tmp\tmp\test.cpp: 在函数‘int main()’中:
D:\Projects\C++\tmp\tmp\test.cpp:36:10: 错误:对‘Derived::func(int)’的调用没有匹配的函数
D:\Projects\C++\tmp\tmp\test.cpp:36:10: 附注:备选是:
D:\Projects\C++\tmp\tmp\test.cpp:26:15: 附注:virtual void Derived::func()
D:\Projects\C++\tmp\tmp\test.cpp:26:15: 附注: 备选需要 0 实参,但提供了 1 个
这是为什么呢?

------解决方案--------------------
第一、如果重新定义继承的方法,应确保与原来的原型完全相同
第二、如果基类声明被重载了,则应在派生类中重新定义所有的基类版本。

你在派生类中只定义了一个没参数的版本,就把基类的有参数的版本隐藏了,因此出错。
------解决方案--------------------
派生类的函数与基类的函数同名,但是参数不同,此时无论有无virtual关键字,base函数将被隐藏。

你可以这样显示的调用:d.Base::func(1);

------解决方案--------------------
楼上的说法正确,你重载了基类的func函数覆盖了不带参的,因为名称相同带参的也被子类给屏蔽了。所以当你将子类运行带参的基类方法时访问不了,所以修改子类函数名,或修改基类带参函数名就能访问了。good luck!
C/C++ code
#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 func1(){
        cout << "Derived::func()" << endl;
    }

};

int main(){

    Derived d;
    d.func();
    d.func(1);
    system("PAUSE");
}

------解决方案--------------------
探讨

感谢楼上各位,我已经了解是为什么了。但是这个可以不可以算是一个语言设计上的BUG呢?从设计上将 它应该被重载吗?按理说 有符号修饰机制的话 我可以使用Base中的func(int)吧?

------解决方案--------------------
c++支持Overloading(重载)、Overriding(重写)。

基类class Base的两个func,是Overloading(重载)关系。
(1) virtual void func(){}
(2) virtual int func( int num ){}

派生类class Derived 的
(3) virtual void func(){}
(3)是(1)的Overriding(重写),但是(3)和(1)绝对不是Overloading(重载)关系。
因为Overloading(重载)的首要前提是两个func要有相同的作用域。

所以我觉得楼主是不是对Overloading(重载)和Overriding(重写)的概念有点混淆。
要想派生类class Derived既支持 d.func(); 又支持d.func(1);。就要这么写:
C/C++ code

class Derived : public Base
{
public:
    using Base::func;
    virtual void func()
    {
        cout << "Derived::func()" << endl;
    }

};

------解决方案--------------------
回16 .

如果没有直接或间接用到的函数,在大多数编译器中会被优化掉.

如果是模板 ,那么没有用到的是肯定不会生成代码的.
------解决方案--------------------
派生类中的同名函数“隐藏”了基类的同名函数(同名变量也会产生隐藏),这里的隐藏不管派生类中同名函数的访问控制如何?例如派生类中的私有fun仍然会隐藏基类中的公有fun(...)//参数任意,只要同名就会发生隐藏。
这其实不是什么重载(这与java中的重载是不一样的),c++中重载必须发生在同一作用域中,基类和派生类根本不在同一作用域,他们的作用域具有包含关系,相当于派生类嵌套在基类中,这与小作用域的同名变量会覆盖大作用域中的同名变量时一个道理(两作用域具有嵌套关系)。
//针对你这个问题,可有两种解决方案。
1.手动暴露基类中的同名变量,在派生类的public下引入 using Base::func; //如果引入到非public下,那么在外界,基类中的func仍然不可见
2.在外部调用基类中的同名函数时,手动指定作用域。 如:d.Base::func(1);