随笔-3  评论-0  文章-0  trackbacks-1
  2011年2月25日

《深度探索C++对象模型》的读书笔记

 

问题域:

由于实现虚拟函数机制将不可避免的打破对象与 C 的二进制兼容性, 需要仔细考虑哪些类才是需要增加虚拟函数机制的.
理论上, 这个范围可以限定在那些必须支持运行期多态(runtime polymorphism)的类. runtime polymorphism 也被称为 active polymorphism, 例如:意图通过基类指针调用子类的 virtual function 实现, 即我们常常提及的多态.
相对的, 可在编译期被解决的则称为 passive polymorphism. 例如, 通过子类实例或指针调用的, 通过class scope operator明确调用的virtual function. 对这类调用, 均将绕开虚拟函数机制, 被当作一般的成员函数进行处理. 这也是 inline virtual function 是有意义的原因.
实际上, 由于编译器实现上的限制, 当类中包含 virtual member function, 即会加入虚函数机制 (即使主要使用方式是 passive polymorphism. 不过这本书出现这么久, 不知道现在编译技术发展如何?).

调用的实现策略:

(具体方式因编译器而异)

单继承

1. 每个类均有自己的virtual function地址表格, 且只有一个.
2. 该类的每个 virtual function 均被指派一个固定表格索引值 (仅对编译器有意义).
a. 每个虚函数的索引值在整个继承体系中保持不变
b. 当子类添加时 virtual function, 使用靠后的表格索引值 (在子类的 virtual function 地址表格中)
c.表格中只有active virtual function, 并非全部虚函数
d.纯虚函数的地址使用pure_virtual_called()或类似函数, 一个被调用时会终止程序的函数(按实现), 担当保护者的角色
3. 在类的实例中增加指向表格的指针

多重继承

Derived 分别继承自 Base1, Base2.

子类中分别包含每个父类的virtual function table指针, 其中被子类改写的虚拟函数的地址已被重新设置. 子类实例的内存布局如下图:
(具体方式因编译器而异, 但包含的元素是一致的)
  1. Base1 subobjects (Base1的成员变量)
  2. Base1 vptr (Base1的virtual function table)
  3. Base2 subobjects
  4. Base2 vptr
  5. Derived subobjects
  6. Derived vptr (书里没写, 个人推测, 当子类具有新的虚拟成员函数时, 将出现其自身的virtual function table)
1 .当使用"第一个"父类的指针调用时, 与单继承的情况相同.
2. 当使用"第N个"父类的指针调用时 (N > 1), 将涉及两个动作
a.取得对应的virtual function table:
在子类指针转换为父类指针时, 已经按照内存布局进行了偏移计算, 于是可以正确得到virtual function table指针. 转换时的代码将类似于(假定N=2): 
ptrBase2 = ptrDerived ? ptrDerived + sizeof(Base1) : 0;
b.将父类指针转换为子类指针, 作为函数参数传入:
由于父类指针是由子类指针+地址偏移得到的, 需要反向转换. 这里提到可以使用thunk技术实现高效转换.
3. 当使用子类指针调用时, 等于是passive polymorphism, 直接编译期解决...


这里仅列出了多重继承问题中我所理解的部分, 实际中还有:"当Base1, Base2有相同签名的虚拟成员函数时, Base1 vptr, Base2 vptr中的地址会被如何设置?", "私有继承, 公共继承混杂又如何"之类的问题. 所以, 珍惜生命, 远离多重继承......
posted @ 2011-02-25 14:32 smart.mk1 阅读(107) 评论(0) 编辑
  2008年10月27日
  • “抽象依赖于一个通用语言,依赖于使用者共同假定某个抽象概念就是指某类事物。”
  • Core, Core Dump:“20th 五六十年代计算机使用铁氧磁芯(Ferrite Cores)作为内部存储设备,当系统崩溃时,就要做“磁芯转储”(Core Dump)。”这就是今天"内核"、"吐核"这个词的由来。例如我们公司用的卡巴6.0经常崩溃,每次崩溃都要吐一下"核",久了不清理就把C盘吐得满满当当...
  • “软件没有磁芯,它就像洋葱拌层层叠叠,每一层都辛辛苦苦的建立于前一层的基础之上,危如累卵,指望着底下那层不要移动或改变太多。”
  • “当让计算机还是程序员更努力工作的选择降临时,还是令人难以决定。”
  • “构建软件系统最难的就是精确设定要做什么东西”----《No Silver Bullet》
  • 一种语言如果让源代码显得丑陋,就会叫苛刻的程序员发疯,仿佛雕塑家遇上了满是硬块的黏土一般。
posted @ 2008-10-27 22:57 smart.mk1 阅读(84) 评论(0) 编辑

使用.NET开发ActiveX控件会碰到如下问题:

  1. 如何实现IObjectSafety接口,向IE表明自己是安全控件。
  2. 如何包装成COM组件,成功在客户端环境注册。
  3. 如何与浏览器脚本语言交互(直接调用JavaScript脚本或者Fire事件)。
  4. 如何处理与浏览器交互的问题,当object属性设置为display:none,让控件在内存中保持活动。
posted @ 2008-10-27 22:44 smart.mk1 阅读(596) 评论(0) 编辑
  
昵称:smart.mk1
园龄:3年7个月
粉丝:0
关注:1
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

搜索

 
 

常用链接

我的标签

随笔档案

最新评论