Avi*_*ash 4 c++ window new-operator
如何过载new和delete操作员dll.我已经将重载运算符写为dll的一部分,但是与此链接的客户端dll不使用overloaded new and delete
以下是C++标准在第17.6.4.6/3节中对此的说法:
使用程序的定义(new/delete运算符)而不是实现提供的默认版本.这种替换发生在程序启动之前.程序的定义不应指定为
inline.无需诊断.
如果你仔细阅读,它确切地解释了你遇到的麻烦.这里发生了一种"捕获22".
一方面,你不能在DLL中编译你的新/删除操作符的定义,因为重载的new/delete不能动态链接(这是因为在加载DLL之前静态初始化期间可能需要new/delete,所以在加载DLL之前和之后你会有不一致的new/delete操作符,这是未定义的行为).
另一方面,您不能只将新的/删除操作符定义放在DLL头文件中,因为它们需要被标记inline以满足一个定义规则(ODR),而一个定义规则(ODR)又不满足以上条款.inline可能存在不标记它们的要求,因为标记的函数定义inline具有"无链接",导致每个翻译单元使用其自己的编译版本(或作为内联扩展),这通常是正常的,但不是动态内存分配.
上述两个捕获的动机都在于,为了正确,通常需要保证分配的存储器new与相应的delete运算符解除分配(即,"汇集在一起",可以说,或者两者都是默认的).例如,如果你的new/delete操作符依赖于底层的malloc/free调用,你依赖于在DLL和可执行文件之间调用new/delete操作符的转换单元使用的堆,不能保证这个堆将是相同的(事实上,在Windows中,特别是,它不是,两个模块使用两个单独的堆进行动态内存分配).
因此,正如鲁克所说,解决问题的方法是"不要那样做".不要重载DLL对象的新/删除操作符,因为没有干净的方法来正确地执行此操作,无论您扭转和转动代码,它总是归结为上述相同的问题.
您可以而且应该做的是为您的DLL对象使用工厂函数模式,并std::shared_ptr使用自定义删除器返回智能指针(例如a ),该自定义删除器依赖于将删除动态分派回创建对象的站点.这是受到Chad Austin的一项技术的启发.我在这里做了一些非常相似的事情.
| 归档时间: |
|
| 查看次数: |
2593 次 |
| 最近记录: |