一个关于继承的问题!

BenKwan 2006-11-27 03:08:47
#include <iostream>
#include <string>

using namespace std ;

class Person
{
public:
string name ;
int age ;


Person()
{
name = "Ben" ;
age = 18 ;
}
//virtual
void GetInfo()
{
cout<<"name: "<<name<<" "<<"age: "<<age<<endl ;
}
void display()
{
this->GetInfo() ;
}
};

class Student : public Person
{
public:
string school;

Student():Person()
{
school = "No.1" ;
}

//virtual
void GetInfo()
{
cout<<"name: "<<name<<" "<<"age: "<<age<<" "<<"school: "<<school<<endl ;
}
};

int main()
{
Person P ;
P.display() ;
P.GetInfo();

Student S ;
S.display() ;
S.GetInfo() ;

cout<<endl ;

Person *p = new Student ;
p->display() ;
p->GetInfo() ;
Student *s = new Student ;
s->display() ;
s->GetInfo() ;

delete p;
delete s;

system("pause") ;
return 0 ;

}

在未使用virtual的情况下为什么P.display() ;和S.display() ; 的结果都是一样~而且都是调用父类的GetInfo方法?这是什么原因?C++的语言机制是怎么对待这种
情况?
...全文
407 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
OOPhaisky 2006-12-02
  • 打赏
  • 举报
回复
在未使用virtual的情况下为什么P.display() ;和S.display() ; 的结果都是一样~而且都是调用父类的GetInfo方法?
------------------------------------------------------------------------------------
因为如果你没有使用virtual,那么那个成员函数就是“静态”,这种non virtual成员函数是在编译时期根据变量的静态类型确定的。
那么现在看你的问题,
Person *p = new Student ;
p->GetInfo() ;
p的静态类型是Person *,因此编译器会根据这个静态类型决定调用Person类的GetInfo()方法。
CAIZHU 2006-12-02
  • 打赏
  • 举报
回复
在方法前面加virtual后 就实现的是动态联遍 就是运行时 通过对象去调用方法 
而在方法前不加virtual 就实现的是静态联遍 在编译的时候 就已经确定了 所以输出的结果就一样了 动态联遍灵活性好 静态联遍速度快 在子类中从写下display方法 那在编译的时候 display就是虚函数了
cruzeflute 2006-12-01
  • 打赏
  • 举报
回复
freebendy(風→繼續吹) ( ) 信誉:100 Blog 2006-12-01 17:57:34 得分: 0


在继承关系中能有重载吗?在继承关系中重写的话都是把父类的方法隐藏了!
我知道在使用virtual的它会调用子类的方法!
我 想问的就是在这里:
Student S ;
S.display() ;
我定义的是一个子类的对象?它的display方法应该是从父类继承下来的!但是为什么它一直调用的是父类的方法?看过一点深入探索C++对象模型~对内存模型有点了解~是不是在编译的时候子类的对象的display方法根据位移来调用其对应的getInfo?在编译时候相对的位移定了?
我想知道的是为什么它会这样显示,c++在处理这种情况的时候机制是什么?

=======================
this->GetInfo() ;事实上就是this->Person::GetInfo() ;
也就是隐藏了类名,所以它和子类的函数是不一样的。
BenKwan 2006-12-01
  • 打赏
  • 举报
回复
在继承关系中能有重载吗?在继承关系中重写的话都是把父类的方法隐藏了!
我知道在使用virtual的它会调用子类的方法!
我 想问的就是在这里:
Student S ;
S.display() ;
我定义的是一个子类的对象?它的display方法应该是从父类继承下来的!但是为什么它一直调用的是父类的方法?看过一点深入探索C++对象模型~对内存模型有点了解~是不是在编译的时候子类的对象的display方法根据位移来调用其对应的getInfo?在编译时候相对的位移定了?
我想知道的是为什么它会这样显示,c++在处理这种情况的时候机制是什么?
missilery 2006-11-28
  • 打赏
  • 举报
回复
应该是重写display,
也就是overwrite display();

override是一个类中有多个同名函数

-----------------
你要重载display
greenteanet 2006-11-28
  • 打赏
  • 举报
回复
因为这里面的display不是虚函数,故都是使用基类的display函数。可以看看C++ Primer Plus里面的13章。
lin_style 2006-11-27
  • 打赏
  • 举报
回复
拿支笔画画它们内存结构就知道了
aniude 2006-11-27
  • 打赏
  • 举报
回复
你要重载display
====
重载是在同一个类里面
jackeylb 2006-11-27
  • 打赏
  • 举报
回复
虚函数向对象看齐;
非虚函数向类型看齐。

子类继承父类时候必须先知道自己的大小,因此要先去遍历父类
lovesnow1314 2006-11-27
  • 打赏
  • 举报
回复
注意这几点:
1 在父类中的成员函数getinfo()没有定义为虚函数,那么public继承的子类默认的为非虚函数,按照C++标准,调用父类非虚函数。
2 如果在父类中成员函数getinfo()为虚汗数,那么子类中不用定义virtual 也默认的为虚汗数,可以实现多态。

从你的代码中看出,父类为非虚,子类没有声明virtual,则无法实现多态。

reference:
http://www.sunistudio.com/cppfaq/virtual-functions.html
bamboostflying 2006-11-27
  • 打赏
  • 举报
回复
你要重载display
taodm 2006-11-27
  • 打赏
  • 举报
回复
看这里:this->GetInfo() ;
this现在的类型是什么?
你cout << typeid(this).name();看一下就知道了。
ouyh12345 2006-11-27
  • 打赏
  • 举报
回复
Student类没有重写display方法,因此它使用的就是Person类的display方法,结果当然一样了。

65,187

社区成员

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

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