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");}
[解决办法]
[解决办法]
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);
[解决办法]
看了你的帖子才知道有这个东西。
仔细想了想,似乎没有什么技术方面的理由来限制楼主想要的东西。但是在隐藏和不隐藏之间,我觉得隐藏更好。从下面三点看(我喜欢三点,呵呵)
1 重写和重载混合出现,本身就会带来代码维护性成本的提升。
2 不编译出错可能会增加你的开发成本,如果不隐藏的函数调用原本不是你的本意的话。
3 由于隐藏带来的编译出错,可以通过using或者再次重写来解决,问题可以得到及时发现。
过高的灵活性带来的不光是效益,还有风险。权衡两者的利弊,显然目前的方案似乎更好。