一个override问题

soulmachine 2008-08-28 09:18:21
最近重温一本C++书,看到这段代码,百思不得其解,请高手解惑!
#include <iostream>

class Base

{

public:

virtual void foo(short)

{

std::cout << "Base::foo(short)" << std::endl;

}

virtual void foo(double)

{

std::cout << "Base::foo(double)" << std::endl;

};

};



class Derived:public Base

{

public:

void foo(short)

{

std::cout << "Derived::foo(short)" << std::endl;

}

void test(void)

{

foo(3.14);//calls Derived::foo(short) !

}

};



int main(int argc,char* argv[])

{

Base* pd = new Derived();

pd->foo(3.14);//calls Base::foo(double) !



Derived d;

d.test();//calls Derived::foo(short) !

return 0;

}
...全文
133 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
家有萌宝V 2008-09-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 e_sharp 的回复:]
C/C++ code Base* pd = new Derived();
pd->foo(3.14);//calls Base::foo(double)
//晚邦定,虚函数在起作用



Derived d;
d.test();//calls Derived::foo(short)
//类型确定就是Derived,不需要晚绑定,虚函数不起作用,Base::foo(double)被Derived::foo(short)隐藏了
[/Quote]
e_sharp 2008-08-29
  • 打赏
  • 举报
回复
    Base* pd = new Derived(); 
pd->foo(3.14);//calls Base::foo(double)
//晚邦定,虚函数在起作用



Derived d;
d.test();//calls Derived::foo(short)
//类型确定就是Derived,不需要晚绑定,虚函数不起作用,Base::foo(double)被Derived::foo(short)隐藏了
soulmachine 2008-08-29
  • 打赏
  • 举报
回复
Derived继承Base时,正准备接受Base的两个函数时(在静态绑定意义下),发现自己有了一个foo(short),而Base的两个foo跟自己的foo(short)不在同一个域,于是打算只接受Base::foo(double),但是这样对待Base::foo(short)是不公平的,干脆两个都不接受,让Derived::foo(short) hide掉那两个,直接不理。 除非你在Derived里用using Base::foo;手动引入Base::foo(double),让Derived在静态意义下也有跟Base一样的函数。

在动态绑定意义下,Base和Derived的虚函数表都有两个函数指针,很简单。Derived的虚函数表有两个槽位,看到自己重写了Base::foo(short),就把自己的foo(short)放到槽位里,而没有实现Base::foo(double),于是直接把Base::foo(double)放到另一个槽位,及默认使用基类的foo(double)。
soulmachine 2008-08-29
  • 打赏
  • 举报
回复
我明白了,我描述一下现在Base和Derived的内存布局吧
Base的虚函数表有两个函数指针,很简单。
Derived继承Base时,正准备接受Base的两个函数时(在静态绑定意义下),发现自己有了一个foo(short),而Base的两个foo跟自己的foo(short)不在同一个域,于是打算只接受Base::foo(double),但是这样对待Base::foo(short)是不公平的,干脆两个都不接受,让Derived::foo(short) hide掉那两个,直接不理。

在动态绑定意义下,很简单,Derived的虚函数表有两个槽位,看到自己重写了Base::foo(short),就把自己的foo(short)放到槽位里,而没有实现Base::foo(double),于是直接把Base::foo(double)放到另一个槽位。
jinwei1984 2008-08-28
  • 打赏
  • 举报
回复
你要看看c++函数调用是怎么进行的
1.确定对象,指针,引用的静态类型
2.在这个类型的类中进行查找,找不到就在基类中查找
3.找到了就进行类型检查
4.生成代码或绑定虚函数


d.test();//calls Derived::foo(short) ! //这地方我也不明白啊,为什么不是调用基类的foo(double)呢?应该是查找派生类的foo(double),

名字查找一旦找到了就不再继续找下去了 首先在派生类中找到了这个函数名foo 然后类型检查,可以转换后调用
编译器有警告(DEV C++)
jinwei1984 2008-08-28
  • 打赏
  • 举报
回复
派生类中的 void foo(short) 覆盖(override)了基类中的virtual void foo(short),
同时隐藏(hide)了基类中的virtual void foo(double);(因为参数不一样,隐藏是要么参数不一样,要么参数一样但是基类函数没有virtual,这里是第一条)
开心爸爸84 2008-08-28
  • 打赏
  • 举报
回复
回复7 楼的, 那个被隐藏了,派生类中如果存在与基类同名函数,且参数类型不同,就会把基类的同名函数隐藏,而不是构成重载,重载只能在相同的作用域中(比如同在基类中)。 如果想用基类的函数的话可以用using Base:foo(double) , 不知道说清楚没
WTK870424 2008-08-28
  • 打赏
  • 举报
回复
#include <iostream>

class Base

{

public:

virtual void foo(short)

{

std::cout << "Base::foo(short)" << std::endl;

}

virtual void foo(double)

{

std::cout << "Base::foo(double)" << std::endl;

};

};



class Derived:public Base

{

public:

void foo(short)

{

std::cout << "Derived::foo(short)" << std::endl;

}

void test(void)

{

foo(3.14);//calls Derived::foo(short) !

}

};



int main(int argc,char* argv[])

{

Base* pd = new Derived();

pd->foo(3.14);//calls Base::foo(double) !



Derived d;

d.test();//calls Derived::foo(short) ! //这地方我也不明白啊,为什么不是调用基类的foo(double)呢?应该是查找派生类的foo(double),
//但是派生类没重写foo(doule),所以就调用基类的。但是结果却不是这样,望高手解答
return 0;

}
开心爸爸84 2008-08-28
  • 打赏
  • 举报
回复

第一个 Overload resolution is done on the static type(here Base) not the dynamic type (here derived)

第二个 见3楼 hide 定义

参照 exceptional C++ Item21

开心爸爸84 2008-08-28
  • 打赏
  • 举报
回复
不好意思没看清题目,不是楼主贴错了
xqls_xqls 2008-08-28
  • 打赏
  • 举报
回复
Base* pd = new Derived(); //将基类的指针指向子类的对象

pd->foo(3.14);// 基类的指针可以调子类由基类派生而来的成员函数void foo(double)

Derived d; //声明一个子类的对象d

d.test();//调用子类的方法,通过子类test方法再调用子类的void foo(short)方法

return 0;

开心爸爸84 2008-08-28
  • 打赏
  • 举报
回复
it is important to differentiate between three common terms:
: To overload a funtion f() means to provide another function with the same name(f) in the sa
same scope but with different parameter types. When f() is actually called , the compileer will try
to pick the best match base ont the actual parameters that are supplied.

To override a virtual fuction f() means to provide another fuction with the same name(f) and the sm
same parameter types in a derived class.

To hide a function f() in an enclosing scope(base class, outer class, or namespace) means to
provide another function with the same name(f) in an inner scope(derived class, nested class, or
namespace), which will hide the same function name in an enclosing scope.


顺便问一下,楼主是不是贴错了,一个类的第二个函数是不是该是test

wangdeqie 2008-08-28
  • 打赏
  • 举报
回复
动态绑定时,先在子类没找到合适的函数时,再在基类里找
wangdeqie 2008-08-28
  • 打赏
  • 举报
回复

//override的是void foo(short)
//这么写,你应该能明白是怎么回事了,楼主
#include <iostream>

class Base

{

public:

virtual void foo(short)

{

std::cout << "Base::foo(short)" << std::endl;

}

virtual void foo(double)

{

std::cout << "Base::foo(double)" << std::endl;

};

};



class Derived:public Base

{

public:

void foo(short)

{

std::cout << "Derived::foo(short)" << std::endl;

}
void foo(double)

{

std::cout << "Derived::foo(double)" << std::endl;

};

void test(void)

{

foo(3.14);

}

};



int main(int argc,char* argv[])

{

Base* pd = new Derived();

pd->foo(3.14);

Derived d;

d.test();

return 0;

}


64,678

社区成员

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

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