面向对象程序设计-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,初始 ...
随机推荐
- UML-类图,包图
UML构造设计模型 一.类图 二.包图 三.组件图 四.部署图 一.类图 1.类:类由三格表示:类名,类的属性,类的操作 类名: 首字母大学 ...
- Epipe
http://www.cnblogs.com/carekee/articles/2904603.html http://blog.chinaunix.net/uid-10716167-id-30805 ...
- 为什么国外程序员爱用苹果 Mac 电脑?
Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里.普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒.那么为什么专业人士也对 Mac 情有独钟呢?从个人 ...
- java常量池理解
String类两种不同的创建方式 String s1 = "zheng"; //第一种创建方式 String s2 = new String("junxiang" ...
- rootvg 镜像
具体操作步骤如下 : a) 查看一下当前可用的硬盘: # lspv hdisk0 0002d74f0e69d97a rootvg ...
- res://ieframe.dll/acr_error.htm 纯手动解决方法
res://ieframe.dll/acr_error.htm 引起这个原因的是,你IE浏览器的扩展组件的问题,因为不知道是具体哪个组件出了问题,所以要采用一刀切的方法来处理: 在开始/或开始键+R, ...
- javascript第五课表达式
c#常用的表达式,一般这里都能用上 例如:三元表达式 var text=20>8? 真 : 假; 表达式?true:flase
- 怎样解决Ubuntu发热严重地问题
刚装ubuntu的时候那是相当地热,hot.直接地原因是没有对应地显卡驱动,然后在software update里面找到Nivida地最新驱动,兴高採烈地装上试一试.一点用处没有! 在网上搜了搜,有一 ...
- 我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)
非常久没有关注RTOS了,所以也一直没有更新.近期闲了,把GPIO I2C调通了.简单移植了Touch.在S5PV210上使用. 调试I2C时.废了非常多周折,最后借助示波器才发现一个小小的错误.折腾 ...
- Ubuntu系统安装stardict(星际译王)词典
直接命令行 sudo apt-get install stardict 安装完毕 启动方法: 1.命令行输入stardict回车 2.高速启动器----搜索stardict直接点击启动. 下载词库: ...