@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋体"; } @font-face{ font-family:"Symbol"; } @font-face{ font-family:"Arial"; } @font-face{ font-family:"黑体"; } @font-face{ font-family:"Courier New"; } @font-face{ font-family:"Wingdings"; } @font-face{ font-family:"新宋体"; } p.0{ margin:0pt; margin-bottom:0.0001pt; layout-grid-mode:char; text-align:justify; font-size:10.5000pt; font-family:'Times New Roman'; } div.Section0{ margin-top:72.0000pt; margin-bottom:72.0000pt; margin-left:90.0000pt; margin-right:90.0000pt; size:612.0000pt 792.0000pt; }

1.多态原理   候杰

为了达到动态系结(后期系结)的目的,C++ 编译器透过某个表格,在执行时期「间接」

呼叫实际上欲系结的函式(注意「间接」这个字眼)。这样的表格称为虚拟函式表(常

被称为vtable)。每一个「内含虚拟函式的类别」,编译器都会为它做出一个虚拟函式表,

表中的每一笔元素都指向一个虚拟函式的位址。此外,编译器当然也会为类别加上一项

成员变数,是一个指向该虚拟函式表的指标(常被称为 vptr)。

虚拟函式表的内容是依据类别中的虚

拟函式宣告次序,一一填入函式指标。衍生类别会继承基础类别的虚拟函式表(以及所

有其他可以继承的成员),当我们在衍生类别中改写虚拟函式时,虚拟函式表就受了影

响:表中元素所指的函式位址将不再是基础类别的函式位址,而是衍生类别的函式位址。

#include <iostream>

#include <cassert>

using namespace std;

class A

{

public:

virtual void print()

{cout << "A/n" ;}

};

class B: public A

{

public:

// void print()

//{cout << "B/n";}

};

class C: public B

{

public:

void print()

{cout << "C/n";}

};

void main()

{

A a ,* pa;

B b;

C c;

a.print();

b.print();

c.print();

pa = & c;

pa->print();

pa = & a;

pa->print();

}

此例在候杰的  深入浅出MFC的例子上改得.

我的理解:根据指针找虚表,调用虚表中的函数,派生类会复制一份虚表,本身若有与父类同名的虚函数,则改之.强制指针类型转换,不会转换虚表.

#include <iostream>

using namespace std;

class CObject

{

public:

virtual void Serialize() { cout << "CObject::Serialize() /n/n"; }

};

class CDocument : public CObject

{

public:

int m_data1;

void print()

{ cout << "print document" << endl;}

void func() { cout << "CDocument::func()" << endl;

Serialize();}

virtual void Serialize() { cout << "CDocument::Serialize() /n/n"; }

};

class CMyDoc : public CDocument

{

public:

int m_data2;

virtual void Serialize() { cout << "CMyDoc::Serialize() /n/n"; }

virtual void onlyDoc()

{ cout << "onlyDoc" << endl;}

};

//---------------------------------------------------------------

class Test

{

public:

virtual void Serialize();

};

void main()

{

CMyDoc mydoc;

CMyDoc* pmydoc = new CMyDoc;

cout << "#1 testing" << endl;

mydoc.func();

cout << "#2 testing" << endl;

((CDocument*)(&mydoc))->func();

// error ((CDocument*)(&mydoc))->onlyDoc();

cout << "#3 testing" << endl;

pmydoc->func();

cout << "#4 testing" << endl;

((CDocument)mydoc).func();   // 所谓的"截断"

cout << "#5 testing" << endl;

((Test*)(&mydoc))->Serialize();

cout << "#6 testing" << endl;

CDocument mt= (CDocument)mydoc; // 所谓的"截断",返回一个新建对象

mt.func();

}

//

#1 testing           //调用子类的中的虚函数

CDocument::func()

CMyDoc::Serialize()

#2 testing

CDocument::func()

CMyDoc::Serialize()

print document

#3 testing

CDocument::func()

CMyDoc::Serialize()

#4 testing

CDocument::func()

CDocument::Serialize()

#5 testing

CMyDoc::Serialize()

E:/test/vc05/learn/Debug>lea

#1 testing

CDocument::func()

CMyDoc::Serialize()

#2 testing

CDocument::func()

CMyDoc::Serialize()

#3 testing

CDocument::func()

CMyDoc::Serialize()

#4 testing

CDocument::func()

CDocument::Serialize()

#5 testing

CMyDoc::Serialize()

#6 testing

CDocument::func()

CDocument::Serialize()

四種不同的物件生存方式(in stack、in heap、global、local static)

#include <iostream>

#include <string>

using namespace std;

class CDemo

{

public:

CDemo(const char* str);

~CDemo();

private:

char name[20];

};

CDemo::CDemo(const char* str) // 建構式

{

strncpy(name, str, 20);

cout << "Constructor called for " << name << '/n';

}

CDemo::~CDemo() // 解構式

{

cout << "Destructor called for " << name << '/n';

}

void func()

{

CDemo LocalObjectInFunc("LocalObjectInFunc"); // in stack

static CDemo StaticObject("StaticObject"); // local static 无论func被调用多少次,静态对象只被初始化一次

CDemo* pHeapObjectInFunc = new CDemo("HeapObjectInFunc"); // in heap

cout << "Inside func" << endl;

}

CDemo GlobalObject("GlobalObject"); // global static

void main()

{

CDemo LocalObjectInMain("LocalObjectInMain"); // in stack

CDemo* pHeapObjectInMain = new CDemo("HeapObjectInMain"); // in heap

cout << "In main, before calling func/n";

func();

cout << "In main, after calling func/n";

}

Constructor called for GlobalObject

Constructor called for LocalObjectInMain

Constructor called for HeapObjectInMain

In main, before calling func

Constructor called for LocalObjectInFunc

Constructor called for StaticObject

Constructor called for HeapObjectInFunc

Inside func

Destructor called for LocalObjectInFunc

In main, after calling func

Destructor called for LocalObjectInMain

Destructor called for StaticObject

Destructor called for GlobalObject

侯杰深入浅出MFC中CPP学习相关推荐

  1. VC++中多线程学习(MFC多线程)二(线程的相关操作、线程间的通信)

    上一篇笼统介绍了如何创建线程以及线程如何和类成员函数通信,本篇将主要介绍: 线程的相关操作 1.线程的挂起和恢复:SuspendThread.ResumeThread 在线程创建并运行后,用户可以对线 ...

  2. 读侯俊杰的《深入浅出MFC》小记

    1.程序必须在产生窗口之前先利用API函数RegisterClass设定属性(我们称此操作为注册窗口类) 2.消息循环中的TranslateMessage是为了将键盘消息转化,DispatchMess ...

  3. MFC第1天--跟踪代码要抓重点--切记切记--侯杰复习C++

    最重要的类:CObject和CCmdTarget 侯杰MFC  C++复习: 三个结论: 1.如果你以一个"基类指针"指向"派生类的对象",那么该指针只能够调用 ...

  4. 21、深入浅出MFC学习笔记,Application Framework简介

    1.Application Framework是一个完整的程序模型:是一组合作无间的对象,彼此藉消息的流动而沟通,并且互相调用对方的函数以求完成任务.<?xml:namespace prefix ...

  5. 深入浅出MFC学习笔记

    深入浅出MFC学习笔记 ithzhang CSDN博客:http://blog.csdn.net/ithzhang/article/category/1159054 转载于:https://blog. ...

  6. 28、深入浅出MFC学习笔记,View功能的加强和重绘效率的提高

    1.同一份Document的多个views,在Document的一个view改变了后,如何同步其它view呢? 让所有的Views 同步更新资料的关键在于两个函数: 1)CDocument::Upda ...

  7. VC++中多线程学习(MFC多线程)一(线程的创建、线程函数如何调用类成员呢?如何调用主对话框的成员?、MFC中的工作线程和界面线程的区别)

    这里废话不多讲了,因为项目原因,需要开启线程进行处理,在不了解线程的情况下,直接百度一下,然后就使用了,结果可想而知,出现了异常,所以花了一天时间系统学习一下多线程,这里主要是针对win32编程方面的 ...

  8. 深入浅出MFC学习笔记 消息

    本章将会对MFC的消息映射和 命令传递机制做深入探讨. MFC规定了消息传递的路线,消息会按照这个路线传递下去,找不到归宿的话就交给DefWindowProc. 在产生窗口之前,如果我们在创建窗口时指 ...

  9. 《深入浅出MFC》学习笔记

    第一章 win32 基本程序概念 windows 是一个"以消息为基础的事件驱动系统".当系统内核捕捉到外围设备发生的事件后,将以一种特定的消息传递出去.而用户程序在接收到相应的消 ...

最新文章

  1. 学习编译原理对下面这段java跳不出死循环大概能有较好的解释吧
  2. Android之底部菜单TabHost的实现
  3. 【Connection Events】【BLE】【原创】
  4. oracle如何查询系统变量数据,Oracle如何对IN子查询使用绑定变量(转)
  5. 洞悉linux下的Netfilteriptables
  6. OpenGL绘制一个三角形的实例
  7. Go 开发关键技术指南 | 为什么你要选择 GO?(内含超全知识大图)
  8. 解决Chrome浏览器不能访问https网站的问题
  9. 电脑怎么卸载软件干净_电脑卸载软件怎么卸载?
  10. 使用matlab生成高斯滤波模板_matlab 高斯滤波(原创)
  11. 京东登录页面html代码_利用Python爬取京东商品的一种办法
  12. 2sk2225代换3A/1500V中文资料【PDF数据手册】
  13. JavaScript基础语法-格式化日期年月日
  14. Mac PHP5.6安装
  15. 编程珠玑之第三章习题8
  16. FFmpeg av_dump_format输出的tbn、tbc、tbr、PAR、DAR的含义
  17. English trip EM3 LP 4B Home Design Relationship Teacher:Ryan
  18. 字节主管工程师年薪中位数 56.4 万美元,排世界第 7,2022 全球程序员收入报告出炉!...
  19. “四书五经”经典语句
  20. 2023年美国大学生数学建模竞赛美赛B题思路分享

热门文章

  1. 简道云-第6章-仪表盘
  2. GLAD中二元光学元件建模
  3. STM32单片机汽车儿童安全系统高温一氧化碳报警WIFI-APP报警
  4. 解题思路-LeetCode第713题:乘积小于K的子数组
  5. 中国汽车HUD行业研究与未来预测报告(2022版)
  6. 2021年广西省安全员A证考试题及广西省安全员A证考试报名
  7. HTML学习笔记8:表单
  8. 金三银四之ConcurrentHashMap剖根问底栏目(二)
  9. 通过 ruffle 使用 WebAssembly 在网页上播放 swf 动画
  10. 独立于计算机系统的是 用户模式,全国计算机二级ms-office选择题题库(同名4921).pdf...