侯杰深入浅出MFC中CPP学习

  @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 stackin heapgloballocal 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值