您的位置:首页 > 编程语言 > C语言/C++

侯杰深入浅出MFC中CPP学习

2009-02-01 13:47 253 查看
@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
////////////////////////////////////////////////////////////////////////////////////////////////////
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: