C++-C++ 虚函数 多态问题
#include <iostream>
#include <string>
using namespace std;
class Base {
public:
virtual ~Base(){}
virtual void display(string str = "Base") {
cout << str << endl;
}
};
class Derive:public Base {
public:
virtual ~Derive(){}
virtual void display(string str = "Derive") {
cout << str << endl;
}
};
int main()
{
Base *pbase = new Derive();
pbase -> display();
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
#include <iostream>
#include <string>
using namespace std;
#include<WINDOWS.H>
class Base {
public:
virtual ~Base(){}
virtual void display(string str /= "Base"/) {
str="Base";
cout << str << endl;
}
};
class Derive:public Base {
public:
virtual ~Derive(){}
virtual void display(string str/* = "Derive"*/) {
str="Derive";
cout << str << endl;
}
};
int main()
{
Base *pbase = new Derive();
string name="Jesse";
pbase -> display(name);//输出Derive
::Sleep(3000);
return 0;
}
总结猜测:应该调用的是Derive的代码区域(派生类vtbl覆盖了基类的代码区域);但是上行转换成Base的指针,display给了默认参数值被当做常量放置在全局静态存储区;而基类的全局静态区域没有被派生类(vtbl)覆盖。所以导致调用的常量是"Base",而代码则是Derive的。
不知道有没有道理呢。不懂查看汇编,否则观察下调用栈,还望证明。
effective C++中有一段关于继承基类带有默认参数的虚函数的调用问题的描述,记得上面是说:虚函数的调用时动态绑定的,而默认参数的则是静态绑定的,代码中pbase的动态类型是Drive,所以调用的函数时Drive类中的display()函数,而pbase的静态类型则是Base,因此默认参数传递的是Base类中的参数
虚函数实现了C++的多态性,用基类指针指向子类地址实现函数的动态联编,
所以,可以肯定pbase -> display(); 调用的肯定是Derive类的display函数,
而输出结果为Base,在于调用的虚函数display()时没有传入参数,而display
是带默认参数的函数,即使用默认参数传入,函数的默认参数是在编译时已经
确定好,运行时不再发生改变;
以下为运行猜想:
分析:Base *pbase = new Derive();
pbase -> display();
这两句其中 Base *pbase = new Derive(); 等价于Base *pbase =(Base)new Derive();
相当于把子类变量强制转换为基类变量,所以只能用pbase指针操作基类已有的成员函数
(子类继承基类,若子类有个print()函数,而基类没有,那么pbase->print()是错误的)
,对于pbase->display();从右边开始执行,它会跳转到基类display(),而display为默认
参数传递,确定传递的参数为“Base”;然后发现此函数为虚函数,动态跳转到子类display
函数,传入参数"Base",所以输出的为"Base";不知道此解释是否合理,待大家验证.