侯杰深入浅出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
////////////////////////////////////////////////////////////////////////////////////////////////////
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学习笔记之VC++ Debug Assertion Failed! 错误(File: strex.cpp Line: 690)
- MFC学习(读MFC深入浅出)
- MFC深入浅出学习心得(每日增加)
- <mfc深入浅出>学习笔记一
- 学习笔记:候捷深入浅出MFC第二章
- VC|MFC学习笔记
- 学习笔记: 源码 solver.cpp 初访
- MFC自绘控件学习总结第二贴
- 深度学习Deeplearning4j 入门实战(3):简介Nd4j中JavaCPP技术的应用
- MFC深入浅出读书笔记第二部分2
- MFC学习笔记(二)
- MFC学习
- cpp学习:文字常量;变量;指针基本概念
- MFC学习笔记-操作篇
- [每日一学]MFC学习笔记——简单计算器
- MFC学习笔记4 VC常用数据类型列表
- 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)
- 深入浅出MFC文档/视图架构之视图
- [每日一学]MFC学习笔记——简单计算器(二)
- MFC OPENCV学习笔记