类继承的virtual方法问题

pur_e 2009-12-07 09:49:44
代码如下,c++ primer中的一个例程,改了下

#include <iostream>
#include <cstdlib>
using namespace std;

class Grand
{
private:
int hold;
public:
Grand(int h = 0) : hold(h) {}
virtual void Speak() const { cout << "I am a grand class!\n";}
virtual int Value() const { return hold; }
};

class Superb : public Grand
{
public:
Superb(int h = 0) : Grand(h) {}
void Speak() const {cout << "I am a superb class!!\n"; }//这里没用virtual修饰
virtual void Say() const//这里使用了,和上面的函数有什么区别呢
{ cout << "I hold the superb value of " << Value() << "!\n";}
};

class Magnificent : public Superb
{
private:
char ch;
public:
Magnificent(int h = 0, char cv = 'A') : Superb(h), ch(cv) {}
void Speak() const {cout << "I am a magnificent class!!!\n";}
void Say() const {cout << "I hold the character " << ch <<
" and the integer " << Value() << "!\n"; }
};

int main()
{
Grand * pg;
Superb * ps;
pg=new Magnificent();
ps=new Magnificent();
pg->Speak();
ps->Speak();
return 0;
}


pg->Speak();
ps->Speak();
的输出都是:
I am a magnificent class!!!
I am a magnificent class!!!

想问的就是:
第一层派生类中两个函数用不用virtual修饰,有什么区别?按照上面的两个输出,感觉Speak函数还是一个虚函数。

是不是基类中声明为虚函数,虚函数表就会存在,派生类是否声明为虚函数就没有区别了,那为啥注释的两个函数Say用virtual修饰,而Speak不用呢
...全文
171 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
VeiwoZouhui 2009-12-07
  • 打赏
  • 举报
回复
1,第一层派生类中两个函数用不用virtual修饰,有什么区别?

答:有区别.不用virtual,那么实例就是基类.你定义的是什么类的指针,就是什么类的指针。
只有虚函数才支持在连接的时候实例化,判别它到底是哪个类的实例

2,是不是基类中声明为虚函数,虚函数表就会存在,派生类是否声明为虚函数就没有区别了,那为啥注释的两个函数Say用virtual修饰,而Speak不用呢.

答:在派生类重载基类的虚函数,可以不加virtual关键字,当然也可以加.
因为在你的第一个基类:Grand里,没有定义say这个函数,因此say 在Superb这个类里定义为需函数,它在这里是定义,不是重载.第一个基类:Grand里,定义了Speak,因此在Superb这个类里为重载,可以不用virtual关键字
pur_e 2009-12-07
  • 打赏
  • 举报
回复
狂汗,是我看的不仔细,晕

virtual void Say() const

这里加virtual是因为基类中没有声明,这里第一次定义、、、、

结贴,谢谢大家了
cx1014 2009-12-07
  • 打赏
  • 举报
回复
我映像虚函数是在多重继承中才需使用,为的是避免二意性,单一继承一般是不必要用virtual修饰的。
weixiaoshashou 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pur_e 的回复:]
引用 1 楼 akirya 的回复:
1 自己重新编译一下不就知道了么
2如果基类的某个虚函数派生类重写了,那么virtual可以省掉.


意思是,如果基类中声明为虚函数了,派生类中无论是否用virtual修饰,都是虚函数是吗?

void Speak() const {cout < < "I am a superb class!!\n"; }//这里没用virtual修饰
virtual void Say() const//这里使用了,和上面的函数有什么区别呢

就是说Superb 类中的这两个函数都是虚函数是吗



[/Quote]
对,如果你的say函数不要virtual的话就不是虚函数了,
honghu069 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pur_e 的回复:]
引用 1 楼 akirya 的回复:
1 自己重新编译一下不就知道了么
2如果基类的某个虚函数派生类重写了,那么virtual可以省掉.


意思是,如果基类中声明为虚函数了,派生类中无论是否用virtual修饰,都是虚函数是吗?

void Speak() const {cout < < "I am a superb class!!\n"; }//这里没用virtual修饰
virtual void Say() const//这里使用了,和上面的函数有什么区别呢

就是说Superb 类中的这两个函数都是虚函数是吗



[/Quote]

是啊,建议找本C++的书看看吧,一般书上都会讲的
weixiaoshashou 2009-12-07
  • 打赏
  • 举报
回复
speak已经继承为虚函数了,
pur_e 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
1 自己重新编译一下不就知道了么
2 如果基类的某个虚函数派生类重写了,那么virtual可以省掉.
[/Quote]

意思是,如果基类中声明为虚函数了,派生类中无论是否用virtual修饰,都是虚函数是吗?

void Speak() const {cout << "I am a superb class!!\n"; }//这里没用virtual修饰
virtual void Say() const//这里使用了,和上面的函数有什么区别呢

就是说Superb 类中的这两个函数都是虚函数是吗


honghu069 2009-12-07
  • 打赏
  • 举报
回复
父类是虚函数,子类不用写virtual,也自动是虚函数了
  • 打赏
  • 举报
回复
1 自己重新编译一下不就知道了么
2 如果基类的某个虚函数派生类重写了,那么virtual可以省掉.

64,642

社区成员

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

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