ATL Style 模板学习手记
来源:互联网 发布:java cp 返回值 编辑:程序博客网 时间:2024/05/17 08:42
ATL Style 模板学习手记
ATL的模板定义有些让人看的眼花缭乱,如,
class CMyWnd : public CWindowImpl
{
...
};
据说,这样做是合法的,原因是C++的语法解释过,即使CMyWnd类只是被部分定义,类名CMyWnd已经被列入递归继承列表,是可以使用的。
将类名作为模板类的参数是因为ATL为了在编译期间的虚函数调用。而真正的虚拟函数,其多态性是在运行时刻决定的。
为此,做程序已观之:
// AtlTemplate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using std::cout;
using std::endl;
class Base
{
public:
void SayHi(){ PrintClassName(); }
protected:
void PrintClassName(){ cout << _T("My class name:/tBase") <};
class D1 :public Base
{
public:
protected:
void PrintClassName(){ cout << _T("My class name:/tD1") <private:
};
class D2:public Base
{
public:
protected:
private:
};
template
class BaseT
{
public:
void SayHi()
{
T* pT = static_cast(this);
pT->PrintClassName();
}
protected:
void PrintClassName(){ cout << _T("My class name:/tBaseT") <};
class TD1 :public BaseT
{
public:
//protected:
void PrintClassName(){ cout << _T("My class name:/tTD1") <private:
};
class TD2 : public BaseT
{};
class TD3 : public BaseT
{
};
int _tmain(int argc, _TCHAR* argv[])
{
D1 d1;
D2 d2;
d1.SayHi();
d2.SayHi();
//---------
TD1 td1;
TD2 td2;
td1.SayHi();
td2.SayHi();
//----
TD3 td3;
td3.SayHi();
getchar();
return 0;
}
最后的输出结果:
My class name: Base
My class name: Base
My class name: TD1
My class name: BaseT
My class name: TD1
对于普通的类Base来说,在基类Base::SayHi()中调用PrintClassName()函数,只能调用自己看得到的函数: Base::PrintClassName
所以D1虽然也定义了PrintClassName,但是没有被调用。
如果将Base中的PrintClassName前面加上virtual,则结果又不一样了。结果D1调用的是自己类的函数D1::PrintClassName;
而后使用的模板,由于在基类中将this指针强制转化成子类,导致可以查看到子类的函数了。如果不用模板,如何能在基类中强制转化成子类呢?真是高明。
ATL的模板定义有些让人看的眼花缭乱,如,
class CMyWnd : public CWindowImpl
{
...
};
据说,这样做是合法的,原因是C++的语法解释过,即使CMyWnd类只是被部分定义,类名CMyWnd已经被列入递归继承列表,是可以使用的。
将类名作为模板类的参数是因为ATL为了在编译期间的虚函数调用。而真正的虚拟函数,其多态性是在运行时刻决定的。
为此,做程序已观之:
// AtlTemplate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using std::cout;
using std::endl;
class Base
{
public:
void SayHi(){ PrintClassName(); }
protected:
void PrintClassName(){ cout << _T("My class name:/tBase") <
class D1 :public Base
{
public:
protected:
void PrintClassName(){ cout << _T("My class name:/tD1") <
};
class D2:public Base
{
public:
protected:
private:
};
template
class BaseT
{
public:
void SayHi()
{
T* pT = static_cast
pT->PrintClassName();
}
protected:
void PrintClassName(){ cout << _T("My class name:/tBaseT") <
class TD1 :public BaseT
{
public:
//protected:
void PrintClassName(){ cout << _T("My class name:/tTD1") <
};
class TD2 : public BaseT
{};
class TD3 : public BaseT
{
};
int _tmain(int argc, _TCHAR* argv[])
{
D1 d1;
D2 d2;
d1.SayHi();
d2.SayHi();
//---------
TD1 td1;
TD2 td2;
td1.SayHi();
td2.SayHi();
//----
TD3 td3;
td3.SayHi();
getchar();
return 0;
}
最后的输出结果:
My class name: Base
My class name: Base
My class name: TD1
My class name: BaseT
My class name: TD1
对于普通的类Base来说,在基类Base::SayHi()中调用PrintClassName()函数,只能调用自己看得到的函数: Base::PrintClassName
所以D1虽然也定义了PrintClassName,但是没有被调用。
如果将Base中的PrintClassName前面加上virtual,则结果又不一样了。结果D1调用的是自己类的函数D1::PrintClassName;
而后使用的模板,由于在基类中将this指针强制转化成子类,导致可以查看到子类的函数了。如果不用模板,如何能在基类中强制转化成子类呢?真是高明。
- ATL Style 模板学习手记
- ATL-Style模板学习
- ATL---style模板
- ATL-Style模板 不用虚函数实现 多态
- ATL/COM 活动模板库学习步骤
- ATL/COM 活动模板库学习步骤
- ATL/COM 活动模板库学习步骤
- ATL/COM 活动模板库学习步骤
- ATL 模板
- ATL-Style类 (模板基类) 定义的一种AV错误
- ATL/COM 活动模板库学习步骤(转载)
- ATL学习
- ATL 学习
- ATL组件模板模拟
- ATL模板原理
- Direct3D学习手记八:模板技术【镜面效果】
- style学习,
- ATL中的CWindowImpl模板类
- The orgin of sports
- AssemblyInfo.cs文件的作用。
- 随想2004-11-11
- 初学Eclipse,完全沒接觸過eclipse的人 不妨看看吧[ZT]
- PRADO v1.6 Tutorial(中文版)
- ATL Style 模板学习手记
- 一些容易遗忘的小技巧
- YFGif播放控件源码介绍
- 韩国人写的让所有中国人汗颜的绝贴!!!
- Visual Basic .Net发送电子邮件
- 弹出窗口详解
- 如何成为一个成功的Jsp程序员?(zt)
- 分页的实现
- 呵呵