jjzjj

c++ - dll 的 new 和 delete 运算符重载

coder 2024-02-17 原文

如何为 dll 重载 newdelete 运算符。我已经将重载运算符作为 dll 的一部分编写,但是与此 dll 链接的客户端不使用 overloaded new and delete

最佳答案

这是 C++ 标准在第 17.6.4.6/3 节中对此的说明:

The program's definitions (of the new / delete operators) are used instead of the default versions supplied by the implementation. Such replacement occurs prior to program startup. The program's definitions shall not be specified as inline. No diagnostic is required.

如果您仔细阅读,它恰好解释了您遇到的问题。这里发生了一种“第 22 条军规”。

一方面,您不能在 DLL 中编译 new/delete 运算符的定义,因为重载的 new/delete 不能动态链接(这是因为在静态初始化期间可能需要 new/delete,然后再加载DLL,所以在加载 DLL 之前和之后你会有不一致的新/删除运算符,这是未定义的行为)。

另一方面,您不能只将 new/delete 运算符定义放在 DLL 头文件中,因为它们需要标记为 inline 以满足单一定义规则 (ODR) ,这反过来又不满足上述条款。要求它们不被标记为 inline 可能是因为标记为 inline 的函数定义“没有链接”,导致每个翻译单元使用它自己的编译版本(或作为内联扩展),这通常是可以的,但不适用于动态内存分配。

上述两个捕获的动机是,为了正确性,通常需要保证使用 new 分配的内存被相应的 delete 释放运算符(即“一起编译”,可以这么说,或者两者都默认)。例如,如果你的 new/delete 运算符依赖于底层的 malloc/free 调用,你依赖于调用 new/delete 运算符的翻译单元使用的堆,在 DLL 和可执行文件之间,不能保证这个堆将是相同的(实际上,在 Windows 中,特别是,它不是,这两个模块使用两个单独的堆进行动态内存分配)。

因此,正如 Rook 所说,解决问题的方法是“不要那样做”。不要为 DLL 对象重载 new/delete 运算符,因为没有干净的方法可以正确地执行此操作,无论您以何种方式扭曲和转换代码,它总是会归结为上述相同的问题。

您可以而且应该做的是为您的 DLL 对象使用工厂函数模式,并返回一个智能指针(例如 std::shared_ptr)和一个依赖于将删除动态分派(dispatch)回创建对象的站点。这是受到来自 Chad Austin 的一项技术的启发。 .我做过非常相似的事情here .

关于c++ - dll 的 new 和 delete 运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11846511/

有关c++ - dll 的 new 和 delete 运算符重载的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  3. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby - 带括号和 splat 运算符的并行赋值 - 2

    我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  10. ruby - 定义自定义 Ruby 运算符 - 2

    问题是:除了在“OperatorExpressions”?例如:1%!2 最佳答案 是的,可以创建自定义运算符,但有一些注意事项。Ruby本身并不直接支持它,但是superatorsgem做了一个巧妙的把戏,将运算符链接在一起。这允许您创建自己的运算符,但有一些限制:$geminstallsuperators19然后:require'superators19'classArraysuperator"%~"do|operand|"#{self}percent-tilde#{operand}"endendputs[1]%~[2]#Out

随机推荐