C++的疑似BUG?

wang2191195 2012-05-08 10:19:41

#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 个
这是为什么呢?
...全文
2385 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
wang2191195 2012-05-17
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 的回复:]

楼主还是没有理解多态啊,什么是动态联编。还是了解下吧
[/Quote]

这应该是名字覆盖问题吧。。。
minilxm 2012-05-16
  • 打赏
  • 举报
回复
楼主还是没有理解多态啊,什么是动态联编。还是了解下吧
谢继雷 2012-05-15
  • 打赏
  • 举报
回复
修正: _draw() 应为 _draw(Image).
谢继雷 2012-05-15
  • 打赏
  • 举报
回复
很好的问题。 显然在 Java 中这种用法是可以的,而且在某些场合特别方便。

因此,LZ的想法可以理解,我觉得这可能是历史遗留的问题,为什么C++选择这种机制,C++历史那本书里没有特别提到,最初可能是考虑到编译器设计,但反正这种机制沿袭下来了就只能遵守了。

考虑一个简单的情况,图像设备 GraphDevice 类上的三个draw函数:
class GraphDevice:
draw(Rectangle)
draw(Circle)
draw(Image)

在一般实现上,draw(Rectangle) 将 Rectangle 转换成 Image,并调用 draw(Image),draw(Circle)类似。在具体实现上就需要重载所有三个 draw 函数,显然非常不便。

有一个简单的解决方案,就是再加上一个 _draw 函数:

virtual draw(Rectangle r): draw((Image) r.rasterize());
virtual draw(Circle c): draw((Image) c.rasterize());
virtual draw(Image m): _draw(m);
virtual _draw() = 0;

在子类中只重写 _draw(),这样就能重用所有的 draw(...) 函数,又能实现多态了。
wang2191195 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 的回复:]

给你一个忠告,轻易不要说是“C++的Bug,Windows的Bug,微软的Bug”……
[/Quote]

嗯 所以才会有疑似BUG这一说。。。
goldmember 2012-05-14
  • 打赏
  • 举报
回复
给你一个忠告,轻易不要说是“C++的Bug,Windows的Bug,微软的Bug”……
tubo_true 2012-05-14
  • 打赏
  • 举报
回复
在派生类加上:
using Base::func; 一句就可以重载了.
wang2191195 2012-05-12
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 的回复:]

引用 11 楼 的回复:

引用 10 楼 的回复:

引用 9 楼 的回复:

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


不是bug 是合理的规定.



在派生类加上:
using Base::func; 一句就……
[/Quote]

嗯 今天刚看到那条 现在才发现EFFECTIVE C++真是一本特别好的书啊 早没看 真是太可惜了!
堂积Code 2012-05-11
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 的回复:]
继承的多态函数必须重定义!
[/Quote]
++
coderchenjingui 2012-05-11
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

引用 10 楼 的回复:

引用 9 楼 的回复:

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


不是bug 是合理的规定.



在派生类加上:
using Base::func; 一句就可以重载了.


嗯 那是……
[/Quote]

Effective C++有解释 为了防止你在程序库或应用框架内建立心得继承类时附带的从疏远的基类继承重载函数。
blueskit 2012-05-10
  • 打赏
  • 举报
回复
把 class Derived : public Base
改为 class Derived : public Virtual Base 看看
wang2191195 2012-05-10
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 的回复:]

有一个问题是如果C++设计成
Derived::func() override了Base中的函数,同时
Derived::func(int) 是继续于Base的,那这样做有什么坏的结果嘛?
[/Quote]

可能可以这么考虑吧 既然我重写了一个 那么说明基类的方法并不实用于我 而基类中的重载就是用来实现类似的功能的 所以就选择隐藏掉吧?
招RD和QA 2012-05-10
  • 打赏
  • 举报
回复
有一个问题是如果C++设计成
Derived::func() override了Base中的函数,同时
Derived::func(int) 是继续于Base的,那这样做有什么坏的结果嘛?
招RD和QA 2012-05-10
  • 打赏
  • 举报
回复
很好的问题,还有答案。
wangxwu 2012-05-10
  • 打赏
  • 举报
回复
看了你的帖子才知道有这个东西。

仔细想了想,似乎没有什么技术方面的理由来限制楼主想要的东西。但是在隐藏和不隐藏之间,我觉得隐藏更好。从下面三点看(我喜欢三点,呵呵)

1 重写和重载混合出现,本身就会带来代码维护性成本的提升。
2 不编译出错可能会增加你的开发成本,如果不隐藏的函数调用原本不是你的本意的话。
3 由于隐藏带来的编译出错,可以通过using或者再次重写来解决,问题可以得到及时发现。

过高的灵活性带来的不光是效益,还有风险。权衡两者的利弊,显然目前的方案似乎更好。
fsy351 2012-05-10
  • 打赏
  • 举报
回复
继承的多态函数必须重定义!
jaychenxiuliang 2012-05-10
  • 打赏
  • 举报
回复
virtual int func( int num ); //函数被覆盖了
wang2191195 2012-05-10
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

把 class Derived : public Base
改为 class Derived : public Virtual Base 看看
[/Quote]

不行 我觉得虚继承在这应该没什么联系吧
Longerandlonger 2012-05-10
  • 打赏
  • 举报
回复
C++复杂体现出来了。重载、重写、模板、继承、虚函数,这些东西一混合在一起。。。你懂的。
wang2191195 2012-05-08
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

c++支持Overloading(重载)、Overriding(重写)。

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

派生类class Derived 的
(3) virtual void func()……
[/Quote]
嗯 可是 在Base中的所有virtual方法 只要没有被重写 都会被继承么?是因为重写了其中某一个同名函数 为了防止程序员乱用 所以默认不继承其它重载的方法呢?
加载更多回复(21)

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧