随便扯扯
针对博客里面的问题随便说几句,其实COM我没怎么用过
http://www.cnblogs.com/mumuliang/archive/2011/01/14/1935792.html
对于疑问1:假设不用纯虚类,类的使用者可以new来创建其实例。那么如果有一天IFastString的开发者突然觉得这个类的实现加一个私有成员变量会更加高效。然后灾难就来了,IFastString这个类的大小变了,于是所有的使用IFastString的人都需要重新编译他的代码。想象一下,windows有一点点的升级,都要重新编译所有的应用程序是多么的可怕。
对于疑问2:出于疑问1的考虑,COM必然选择纯虚类作为接口。类的使用者不知道类的实现,所以无法创建类的实例(没法new). 于是COM实现了一种create by name的机制,把类的创建交给了类的实现者。既然类的创建是一个函数CoCreateInstance而不是直接调用new和构造函数,那么摧毁这个类的时候也就不应该调用析构函数,析构函数的调用者自然应该是构造函数的调用者。假设是类的使用者调用了delete p; 那么万一类的实现者重载了delete, 这两个delete根本不通用怎么办。
疑问2的补充:
我不同意他的理由。虚析构函数和其他虚函数的实现本没有什么区别。或者说标准本没规定在实现他们上需要有什么区别。
我理解是这样的,在C++里面new和delete必须是对应的。怎么样new出来的东西,就该怎么delete.
假设类的实现者使用如下的方式创建类实例
B *p = new B;
B *pp = new B[10];
那么类的使用者怎么调用delete呢? 所以,类的销毁只能交给类的实现者来做。
还有,delete是个操作符(operator),他本身不是虚函数。delete的逻辑是这样的
先调用类的析构函数
然后调用operator delete去回收内存。
(注:C++中delete和operator delete是两个东西,delete不可被重载,而operator delete可以被重载,同样的也存在new/operator new)
既然operator delete可以被重载,那么问题就出来了。类的使用者的operator delete不一定能够和类的实现者的operator new匹配。
既然不该由类的使用者销毁对象实例,那么也就没有理由把析构函数作为虚函数了,否则类的使用者调用了析构函数,回头类的实现者再调用一次析构函数不就麻烦了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述