面向对象程序设计-C++_课时24多态的实现
所有带virtual的类的对象,里面最上面有一个隐藏的指针vptr,指向一张表vtable
#include <iostream>
using namespace std; class A
{
public:
A() :i() {}
virtual void f() { std::cout << "A::f()" << std::endl; }
int i;
}; void main()
{
A a, b;
a.f(); std::cout << sizeof(a) << std::endl;//8,不是4 int *p = (int *)&a;
int *q = (int *)&b; int *x = (int *)*p; std::cout << *x << std::endl; std::cout << *p << " " << *q << std::endl;//一样 system("pause");
}
产生运行时的多态性有如下3个前提:
(1)类之间的继承关系满足赋值兼容性规则
(2)改写了同名虚函数
(3)根据赋值兼容性规则使用指针(或引用)
#include <iostream>
using namespace std; class A
{
public:
A() :i() {}
virtual void f() { std::cout << "A::f()" << i << std::endl; }
int i;
}; class B :public A
{
public:
B() :j() {}
virtual void f() { std::cout << "B::f()" << j << std::endl; }
int j;
}; void main()
{
A a;
B b; A *p = &a; int *r = (int *)&a;
int *t = (int *)&b; *r = *t; p->f(); //B *q = &a;
//error C2440: “初始化”: 无法从“A *”转换为“B *”
//note: 从基类型到派生类型的强制转换需要 dynamic_cast 或 static_cast a = b; a.f();//A::f()10,必须使用指针或者引用,这样才可以实现多态性 system("pause");
}
只有基类的析构函数被说明为虚函数,则派生类的析构函数,无论是否使用virtual进行说明,都自动地成为虚函数
如果一个类中定义了虚函数,析构函数也应说明为虚函数,尤其是在析构函数要完成一些有意义的任务时,例如释放内存等
面向对象程序设计-C++_课时24多态的实现的更多相关文章
- 面向对象程序设计-C++_课时30运算符重载——基本规则_课时31运算符重载——原型_课时32运算符重载——赋值_课时33运算符重载——类型转换
区分初始化,赋值 #include <iostream> using namespace std; class Fi { public: Fi() {}//1构造函数 }; class F ...
- 面向对象程序设计-C++_课时28静态对象_课时29静态成员
Static in C++ Two basic meanings Static Storage --allocated once at a fixed address Visibility of a ...
- 面向对象程序设计-C++_课时26拷贝构造Ⅰ_课时27拷贝构造Ⅱ
一旦写了一个类,给它3个函数: 1default construtor 2virtual destructor 3copy constructor Constructions vs. assignme ...
- 面向对象程序设计-C++_课时22向上造型
赋值兼容规则是指在公有派生情况下,一个派生类的对象可以作为基类的对象来使用的情况. 约定类derived是从类base公有派生而来的,则指如下3种情况: (1)派生的对象可以赋给基类的对象.例如: d ...
- 面向对象程序设计-C++_课时21引用
数据类型 & 别名=对象名; #include <iostream> using namespace std; int * f(int * x) { (*x)++; return ...
- 面向对象程序设计-C++_课时19const_课时20不可修改的
error C2131: 表达式的计算结果不是常数 #include <iostream> using namespace std; void main() { ; int finalGr ...
- 面向对象程序设计-C++_课时18内联函数
使用inline说明的函数称内联函数. 在C++中,除具有循环语句.switch语句的函数不能说明为内联函数外,其他函数都可以说明为内联函数. #include <iostream> us ...
- 面向对象程序设计-C++_课时17函数重载和默认参数
函数重载,区别一是参数类型不同,二是参数个数不同. 默认参数可以多于1个,但必须放在参数序列的后部. 尽量不要用默认参数,会影响阅读 error C2668: “f”: 对重载函数的调用不明确 #in ...
- 面向对象程序设计-C++_课时16子类父类关系
初始化列表 类名::类名(形参1,形参2,...形参n):数据成员1(形参1),数据成员2(形参2),...,数据成员n(形参n) { ... } 规则1,初始化列表进行数据成员的初始化 规则2,初始 ...
随机推荐
- html中的圆角边框
border-radius:20px; radius:以某某为半径画圆. 如何制作一个圆形: div{height:150px;//像素的一半,再加上边框的像素 width:150px; border ...
- modbus rtu 协议转DLT645-2007和DLT645-1997电表协议转换器定制,
现场会碰到现场数据为Modbus协议,但是后台系统为DLT645协议系统,本模块支持将工业ModbusRtu协议转换为电表国标协议DLT645协议,支持1997和2007俩种标准,只需要进行简单的配置 ...
- gridview外边距
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区. 您需要 登录 才可以下载或查看,没有帐号?注册 x 本帖最后由 同舟 于 2013-9-30 11:44 编辑 最新项目需要个单行显示功能键 ...
- 转自:Python函数式编程指南(二):函数
2. 从函数开始 2.1. 定义一个函数 如下定义了一个求和函数: 1 2 def add(x, y): return x + y 关于参数和返回值的语法细节可以参考其他文档,这里就略过了. ...
- relatedTarget, fromElement, toElement
原文:http://www.quirksmode.org/js/events_mouse.html#relatedtarget W3C在mouseover和mouseout事件中添加了relatedT ...
- PHP自定义函数与字符串处理
自定义函数: 1.默认值的函数: function Main($a=5,$b=6) { echo $a*$b; } 2.可变参数的函数: function ...
- iOS图片模糊效果
增加 CoreImage.framework CoreGraphic.framework 等库 在使用时引入:#import <Accelerate/Accelerate.h> ,支持 ...
- 用事件与CSS改变按钮不同状态下的颜色
目标效果: 表单的群发按钮,在鼠标悬停时为深蓝色,鼠标离开时为淡蓝色. HTML代码: <button id="submitBtn" class="btn&quo ...
- SQL Server数据库---》基础
SQL Server:只是操作数据库的一个工具(这种工具,只是提供一个界面化的方式让用户方便操作数据库) 开启服务:点击:我的电脑(计算机)--管理--服务和应用程序--服务--开启SQL Serve ...
- [转载自 文顶顶]iOS开发UI篇—程序启动原理和UIApplication
一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个应用都有自己的UIApplica ...