虚函数和重载函数

smjacky 2006-10-29 03:33:50
class B
{
public:
virtual void func1(){
cout<<"class B :: func1()"<<endl;
}
};

class D : public B
{
public:
void func1(char){
cout<<"class D :: func1()"<<endl;
}
};


int _tmain(int argc, _TCHAR* argv[])
{
D* d = new D;
d->func1();//error
return 0;
}

如上代码,在编译的时候,在d->func1()报错,说D::func1()不接受0参数
有点疑惑,D的虚函数表中不是有func1()吗?!!!

如果把D* d = new D;改成B* d = new D;就没错误了
或者在D的定义中把void func1(char)这个函数去掉,也没错误了

高人指点一下,在编译器内部是如何处理,才会有这个结果的
...全文
403 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
aniude 2006-12-18
  • 打赏
  • 举报
回复
如果把D* d = new D;改成B* d = new D;就没错误了
或者在D的定义中把void func1(char)这个函数去掉,也没错误了

B* d = new D
下面又是void func1(char)的话,不能符合c++多态的定义,那么只能是根据d类型决定。自然是调用B的func1()

把void func1(char)改掉,D* d = new D;在子类中找不到函数,就只能在父类里面 找
eqxu 2006-12-18
  • 打赏
  • 举报
回复
请查看http://blog.csdn.net/fisker0303/ C++对象布局及多态实现的探索
lann64 2006-10-30
  • 打赏
  • 举报
回复
to blldw(how)
2、一提到重载函数必然是涉及两个以上的函数,而且这些函数仅仅是函数名相同,而函数的输入参数和返回类型必定有一样是不同的
-------------------------
仅仅返回类型不同是不能构成重载的,会编译出错(多重定义)
重载必须是至少一个参数上有区别。
blldw 2006-10-30
  • 打赏
  • 举报
回复
1、重载函数和虚函数是不同的
2、一提到重载函数必然是涉及两个以上的函数,而且这些函数仅仅是函数名相同,而函数的输入参数和返回类型必定有一样是不同的
3、虚函数的一个重要特点是在声明时在返回值类型前加virtual关键字,在派生类中的函数此时如果和函数的返回类型、函数名称和函数输入参数都和基类中的虚函数相同,则即使在派生类中不在该函数前加virtual关键字,该函数依然为虚拟函数
4、虚拟函数的一个主要特征就是可以在运行时可根据实际对象来调用实际对象中的函数。
在你的例子中,由于类D中的func1()并不存在,当然调用时就会出错
hhhhhnnnnn66 2006-10-30
  • 打赏
  • 举报
回复
main()这样写看看区别吧:
int _tmain(int argc, _TCHAR* argv[])
{
B* b = new B;
b->func1();

D *d = new D;
b=d;
b->func1();
return 0;
}
lann64 2006-10-29
  • 打赏
  • 举报
回复
楼主再去复习一下隐藏(hide)的概念。
只要派生类定义了基类里同名函数,基类中所有同名的函数都被隐藏。只有一个例外,就是这个函数在基类里定义为virtual,并且,派生类定义的函数同基类的函数在返回类型和参数上完全一致。这时候,是override。也就是楼主期待的多态。可惜,楼主给的例子里,不满足第二个条件,实际上基类的函数被隐藏了,而不是override。
被隐藏的函数可以用显式调用。明确指出此处调用基类的函数。base::fun()。
cwl_feng 2006-10-29
  • 打赏
  • 举报
回复
或者
class B
{
public:
virtual void func1(){
cout<<"class B :: func1()"<<endl;
}
};

class D : public B
{
public:
void func1(){
cout<<"class B :: func1()"<<endl;
}
void func1(char){
cout<<"class D :: func1()"<<endl;
}
};


int _tmain(int argc, _TCHAR* argv[])
{
D* d = new D;
d->func1();//error
return 0;
}
cwl_feng 2006-10-29
  • 打赏
  • 举报
回复
class B
{
public:
virtual void func1(){
cout<<"class B :: func1()"<<endl;
}
};

class D : public B
{
public:
void func1(char){
cout<<"class D :: func1()"<<endl;
}
};


int _tmain(int argc, _TCHAR* argv[])
{
D* d = new D;
d->B::func1();//error
return 0;
}
jiang_nan1981 2006-10-29
  • 打赏
  • 举报
回复
nod,把d->func1();//error
改成 d->B::func1();
就可以了
nule 2006-10-29
  • 打赏
  • 举报
回复
纠正楼上几个错误:
1、楼上说“并没有对b中虚函数func重载”。重载和覆盖的概念是不同的,请进一步研究。
2、之所以用一个D指针指向D对象是没有能调用从B继承过来的func1()函数,是因为,D中的func1(char)隐藏了B中的func1函数,在D中只能看到func1(char).

关键是区别重载(overload),覆盖(override),隐藏(hide)之间的区别。
xiaojun789 2006-10-29
  • 打赏
  • 举报
回复
在你的类D只是继承了类B但是并没有对b中虚函数func重载,所以当你执行d->func1()时调用的类D的成员函数func1(char).所以会报错。
当该成B* d = new D时,执行d->func1()是调用的类B的成员函数func1()
beginnow 2006-10-29
  • 打赏
  • 举报
回复
不是虚函数,也不属重载,有错误了
飞哥 2006-10-29
  • 打赏
  • 举报
回复
void func1(char)
这个把参数去掉就是了
飞哥 2006-10-29
  • 打赏
  • 举报
回复
虚函数要参数一致~

65,210

社区成员

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

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