关于 ATL 中 CComControl 的构造
分享一篇 C++语言 & ATL 的高阶解读笔记,你需要在C++语言特性中上串下跳,应该算篇有质量的文章。
class ATL_NO_VTABLE CHello :
// ...
public CComControl<CHello>
{
// ...
}
叶子类,继承CComControl,将自己作为模板参数传入。(ATL贯彻全场的静态多态技巧)
template <class T, class WinBase = CWindowImpl< T > >
class ATL_NO_VTABLE CComControl : public CComControlBase, public WinBase
{
public:
CComControl() : CComControlBase(m_hWnd) {}
// ...
}
CComControl有个默认模板参数CWindowImpl,而CWindowImpl也使用叶子类作为其模板参数。
在初始化列表中CComControlBase使用的m_hWnd来得有点妖怪:
m_hWnd是WinBase带来的(多重继承)
m_hWnd这时候没有 有效的值
因为 子对象CComControlBase 先于 子对象WinBase构造,而 子对象WinBase 只是分配了内存(见下条解释)
这里违背了“按声明次序使用”的原则,使用了没有初始化的成员,进入危险地带。
m_hWnd这时候 有 有效的内存空间。
因为叶子对象CHello已经分配了空间,正在通过 构造函数 建立各成员变量的初值。
尽管CComControlBase使用了一个没有初始化的、叶子类带来的成员变量,但小心使用依然有效。
class ATL_NO_VTABLE CComControlBase
{
public:
CComControlBase(HWND& h) : m_hWndCD(h)
{
memset(this, 0, sizeof(CComControlBase));
m_phWndCD = &h;
// ...
}
// ...
// Attributes
public:
#pragma warning(push)
#pragma warning(disable: 4510 4610) // unnamed union
union
{
HWND& m_hWndCD;
HWND* m_phWndCD;
};
#pragma warning(pop)
// ...
}
这里进入CComControlBase神奇的构造函数
它将自己(作为一个子对象)所拥有的内存清零:起始地址this,清零长度自己的大小sizeof(CComControlBase)
注意它的参数是一个引用,这里 传值 与 传引用 将有迥然不同的区别(而不是过去的差不多,主要是优化)
m_phWndCD赋值为 参数的地址。语言特性小考场:由于参数是引用,引用的取地址值,与引用所值对象地址一致。
回到CComControl构造函数初始化列表问题,子对象CComControlBase的m_phWndCD现在指向,另一个子对象WinBase中的m_hWnd成员。
设计讨论:CComControlBase为使用一个HWND参数,没有进一步使用模板,而是简单的使用一个成员变量。虽然CComControlBase子对象和WinBase子对象都住在一个家中——CHello叶子对象里,CComControlBase应有可能使用模板,进一步的将m_phWndCD所占内存开销去掉。为啥没有呢?是为了避免过多的纠缠、变复杂化(以易于独立思考、理解),还是HWND需要一定的独立性?
语言特性弯弯绕绕:再遇union的效用
语言书上说“引用一经复制,便不能修改”,幽暗的世界里这不是事实。此处应该使用了语言实现的一些底层特性,以及Windows编程时的一些命名约定。
匿名union让m_hWndCD与m_phWndCD共用一个内存,通过对m_phWndCD的修改,我们改变了引用m_hWndCD的值!
介于Windows编程的命名约定,我们习惯了m_pXXX == & m_XXX 这样的惯例,此处同样成立
&m_hWndCD == m_phWndCD
*m_phWndCD == m_hWndCD
有点抓狂,对同一个内存的两种访问方法,居然得到相同的值,更有甚者 m_hWndCD == m_hWnd,这绝对是对C++语言意志力的考验!
关于 ATL 中 CComControl 的构造的更多相关文章
- ATL中窗口句柄与窗口过程的关联方法
ATL中采用了一种动态生成机器指令的方式进行窗口句柄与窗口对象进行关联,以是详细分析: CWindowImpl会在第一次调用Create时注册窗口类,该窗口类是的信息是在CWindowImpl的子类中 ...
- Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-97讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)
我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...
- 第81讲:Scala中List的构造和类型约束逆变、协变、下界详解
今天来学习一下scala中List的构造和类型约束等内容. 让我们来看一下代码 package scala.learn /** * @author zhang */abstract class Big ...
- [Leetcode] Construct binary tree from preorder and inorder travesal 利用前序和中续遍历构造二叉树
Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume tha ...
- ATL中宏定义offsetofclass的分析
近日学习ATL,通过对宏定义offsetofclass的解惑过程.顺便分析下虚函数表,以及通过虚函数表调用函数的问题. 1 解开ATL中宏定义offsetofclass的疑惑 #define _ATL ...
- LeetCode105 从前序和中序序列构造二叉树
题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9 ...
- Vue中的Xss构造
首发tools:https://www.t00ls.net/thread-59512-1-1.html 存储型XSS 最近做测试的时候碰到了一个前端页面使用了Vue框架的项目 在测试XSS漏洞的过程中 ...
- 在Asp.Net MVC中使用ModelBinding构造Array、List、Collection以及Dictionary
在asp.net mvc中,我们可以在html表单中使用特定的格式传递参数,从而通过model binder构造一些集合类型. 第一种方式 public ActionResult Infancy(Pe ...
随机推荐
- 暴力破解-DVWA_1.9-笔记
穷举法 通过社工尽可能的缩小密码字典的范围 所用到的工具: Firefox浏览器及其插件Proxy Switcher, OWASP ZAP代理抓包工具. OWASP ZAP 代理抓包工具 h ...
- CF486B OR in Matrix(构造+思维)
CF486B 一道有趣的思维题 由于or的性质可知只要a[i][j]为1那么b中第i行,第j列将都变成1 相反的,如果b[i][j]是0那么a中第i行,第j列都必须是0 根据第二个性质我们可以构造出a ...
- Notepad++ 不打开历史文件
1. 自己的很多虚拟机上面安装了notepad++ 提高编辑文件的速度. 但是发现 有时候总是默认打开 很多 历史文件 会造成很卡顿. 2. 解决办法 如下图 设置->首选项 3. 具体的位置为 ...
- [转帖]查看ubuntu 各系统的内核版本
查看ubuntu 各系统的内核版本 https://www.cnblogs.com/ranxf/p/6923311.html /etc/issue /proc/version 1.查看ubuntu版本 ...
- springmvc中的视图模型的返回方式
way1:略过; way2:(神似way1)通过在方法的参数中添加一个Model类型的参数,,该参数由spring自动生成传入, 然后在方法内部使用addAttribute()方式添加模型数据, 最后 ...
- 解决 "Could not autowire. No beans of 'SationMapper' type found" 的问题
网上查找的方法,附上原文链接:https://blog.csdn.net/Coder_Knight/article/details/83999139 方法1:在mapper文件上加@Repositor ...
- Delphi 对象观察器
- 6U VPX 加固智能计算异构服务器
6U VPX 加固智能计算异构服务器 北京太速科技有限公司在线客服:QQ:448468544 公司网站:www.orihard.com联系电话:15084122580
- Qualcomm_Mobile_OpenCL.pdf 翻译-7 内存性能优化
内存优化是最重要也是最有效的OpenCL性能优化技术.大量的应用程序是内存限制而不是计算限制.所以,掌握内存优化的方法是OpenCL优化的基础.在这章中,将会回顾OpenCL的内存模型,然后是最优的实 ...
- CSS布局方式
1.内边距 padding <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...