谭浩强的C++中发现一处地方好像有点问题

a2471388918 2013-09-22 12:27:13
在书上好像有点问题,不知道是不是我理解错,还是他写错了,原文是:(C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。)
#include <iostream>
using namespace std;
class t{
public :
virtual void show(){
cout<<"t"<<endl;}};

class tt:public t{
public :
void show(){
cout<<"tt"<<endl;}
virtual void show(int n){// 1,如果不自己弄成虚的话 ,
cout<<n<<" 2tt"<<endl;}
};

class ttt:public tt{
public :
void show(int n){
cout<<n<<" 3tt"<<endl;}
};

int main(){
tt t2;
ttt t3;
t*p=&t3;
p->show();
tt*pp=&t3;
pp->show(5);//(接上)输出的是2tt,也就是tt类
return 0;
}


他不是说所有的同名都变虚了吗,那第一个t我把那个void show()变成了虚,那接下来的void show(int n)也应该是虚的吧。
我在plus(挺喜欢的,比那个c++prime 容易理解,至少目前是。c++prime 很少看)上找不到相关说明哦,
...全文
537 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
halleyzhang3 2013-09-27
  • 打赏
  • 举报
回复
没必要纠结这些问题,实际情况以你用的编译器为准就行了。话说我怎么记得虚函数和非虚函数名字一样参数不同会有个警告呢。
a2471388918 2013-09-26
  • 打赏
  • 举报
回复
引用 25 楼 yulitingfeng 的回复:
老谭的书没问题,有问题的是人。 show() show(int) 算不上是同名函数。
没错,有问题的是人,那个人是你。因为书中还有一句话共同说明同名不是都相同。
无间星火 2013-09-26
  • 打赏
  • 举报
回复
引用 3 楼 max_min_ 的回复:
谭的书就不要再看了,太多害人的东西。。。。 换本 c++ primer吧
c++primer实在不适合入门啊,我是先看谭浩强的书,再看c++primer的,这样才看得懂C++primer,不然实在看不懂c++primer啊
SmallCoder1992 2013-09-26
  • 打赏
  • 举报
回复
我的话可能说的不对,我的语言能力差了,还是自己看我的话,希望你能明白我的意思
SmallCoder1992 2013-09-26
  • 打赏
  • 举报
回复
注意一点,只要在继承类中出现和基类中的virtual不同的就是出现对基类中的virtual进行了隐藏,其实不管是不是virtual都是一样
u012257738 2013-09-26
  • 打赏
  • 举报
回复
书上没有错,虚函数的使用 (1)在基类用virtual声明成员函数为虚函数,这样就可以在派生类中重新定义此函数 (2)在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同, 可以对照下你的。
a2471388918 2013-09-24
  • 打赏
  • 举报
回复
引用 20 楼 ZLhy_ 的回复:
看到你的问题和LS的回复,基本上可以把矛盾集中在作用域和二义性,以及覆盖和重载的关系上了。 在执行C++代码时,编译器会从小范围作用逐步向外层作用扩展去搜索名字或是标示符。就像是代码中的第一次输出的是tt类中的void show();函数,因为在ttt中没有找到该函数,编译器就会去更大的作用于去找,结果在其父类tt中找到了满足的函数,于是就输出了。其中的有些话是摘自C++ Primer的
引用 8 楼 shb8845369 的回复:
确切地讲,函数名称、参数个数、参数类型和参数顺序四个条件全部满足才能称得上是同名函数。如果只是函数名相同,而其他条件只要一个没有满足,就是函数重载。另外如果只是函数的返回值不同,其他都相同也不是函数重载,因为函数的返回值完全可以通过强制转换,因此C++编译器没有将函数返回值作为函数重载的判断依据。多接触几遍,楼主自然会了然于胸。
只有在同一个类,或者说是同一个作用域才可以重载,不同类之间的继承是没有重载这个观念的,有这个的书都是错的。就像谭浩强的。
iamnobody 2013-09-24
  • 打赏
  • 举报
回复
引用 16 楼 taodm 的回复:
楼主,蹉跎青春有很多种办法,没必要用谭老的破书啊。
瘦又美 2013-09-24
  • 打赏
  • 举报
回复
yulitingfeng 2013-09-24
  • 打赏
  • 举报
回复
老谭的书没问题,有问题的是人。 show() show(int) 算不上是同名函数。
昆仑道长 2013-09-24
  • 打赏
  • 举报
回复
引用 23 楼 a2471388918 的回复:
[quote=引用 20 楼 ZLhy_ 的回复:] 看到你的问题和LS的回复,基本上可以把矛盾集中在作用域和二义性,以及覆盖和重载的关系上了。 在执行C++代码时,编译器会从小范围作用逐步向外层作用扩展去搜索名字或是标示符。就像是代码中的第一次输出的是tt类中的void show();函数,因为在ttt中没有找到该函数,编译器就会去更大的作用于去找,结果在其父类tt中找到了满足的函数,于是就输出了。其中的有些话是摘自C++ Primer的
引用 8 楼 shb8845369 的回复:
确切地讲,函数名称、参数个数、参数类型和参数顺序四个条件全部满足才能称得上是同名函数。如果只是函数名相同,而其他条件只要一个没有满足,就是函数重载。另外如果只是函数的返回值不同,其他都相同也不是函数重载,因为函数的返回值完全可以通过强制转换,因此C++编译器没有将函数返回值作为函数重载的判断依据。多接触几遍,楼主自然会了然于胸。
只有在同一个类,或者说是同一个作用域才可以重载,不同类之间的继承是没有重载这个观念的,有这个的书都是错的。就像谭浩强的。[/quote] 我是这么来理解重载和覆盖的,请看例子:

class Parent
{
  public:
  virtual void Func(int);
}

class ChildOverride:public Parent
{
  public:
  void Func(int, int);
}//情形一,重载

class ChildOverlay:public Parent
{
 public:
  void Func(int);//这里可以不明确写出virtual关键词,但编译器认为virtual void Func(int);完全一样.
}//情形二,覆盖
在我看来,类ChildOverride在内存中其实包含两个函数virtual void Parent::Func(int)void ChildOverride::Func(int,int),我认为这相当于就是函数重载,只是不那么直观;而类ChildOverlay经过编译器的解释后,在内存中只有void ChildOverlay::Func(int)一个函数在虚表(virtual table)中,这个我才认为是覆盖。不知我现在说清楚了没~
疯狂的红豆 2013-09-24
  • 打赏
  • 举报
回复
看到你的问题和LS的回复,基本上可以把矛盾集中在作用域和二义性,以及覆盖和重载的关系上了。 在执行C++代码时,编译器会从小范围作用逐步向外层作用扩展去搜索名字或是标示符。就像是代码中的第一次输出的是tt类中的void show();函数,因为在ttt中没有找到该函数,编译器就会去更大的作用于去找,结果在其父类tt中找到了满足的函数,于是就输出了。其中的有些话是摘自C++ Primer的
a2471388918 2013-09-23
  • 打赏
  • 举报
回复
引用 16 楼 taodm 的回复:
楼主,蹉跎青春有很多种办法,没必要用谭老的破书啊。
引用 18 楼 u010253589 的回复:
建议看C++ primer吧
引用 15 楼 VisualEleven 的回复:
谭浩强的书还是给扔了吧~
引用 11 楼 FrankHB1989 的回复:
谭浩强的书LZ看到这里只发现一个问题么。sigh. 省略virtual当然是指对相同签名的overrider。
引用 7 楼 lin5161678 的回复:
谭书 常常会造成误导 不过这里嘛 还可以 强词夺理 一下 对于C++来说 函数名 可以把参数列表也算上去 就是 func() func(int) 函数名不同 ................... 好吧 还是觉得有点扭曲啊
你们反差很大啊,我就是随便翻翻嘛,不过我还是喜欢plus那本。那本c++primer太简单话了,很多内容一句话概括,plus都有很好的解释
max_min_ 2013-09-22
  • 打赏
  • 举报
回复
谭的书就不要再看了,太多害人的东西。。。。 换本 c++ primer吧
a2471388918 2013-09-22
  • 打赏
  • 举报
回复
引用 1 楼 ananluowei 的回复:
void show(int n) 这个不是虚的,参数不一样。参数和返回值必须一样才行。
从测试看确实不是虚的,但他的话不是说同名的都变为虚了吗,那在tt那里void show(int n)就应该变为虚了啊,接下来就也虚。
大尾巴猫 2013-09-22
  • 打赏
  • 举报
回复
void show(int n) 这个不是虚的,参数不一样。参数和返回值必须一样才行。
DevilDust 2013-09-22
  • 打赏
  • 举报
回复
建议看C++ primer吧
Enockipp 2013-09-22
  • 打赏
  • 举报
回复
楼主可以去看下c++primer第四版的p477: 派生类中的虚函数的声明必须与基类中的定义方式完全匹配,但有一个例外:返回对基类型的引用(或指针)的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用(或指针)
lin5161678 2013-09-22
  • 打赏
  • 举报
回复
谭书 常常会造成误导 不过这里嘛 还可以 强词夺理 一下 对于C++来说 函数名 可以把参数列表也算上去 就是 func() func(int) 函数名不同 ................... 好吧 还是觉得有点扭曲啊
乃不知有汉 2013-09-22
  • 打赏
  • 举报
回复
引用 3 楼 max_min_ 的回复:
谭的书就不要再看了,太多害人的东西。。。。
+1
加载更多回复(11)

64,654

社区成员

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

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