【问题标题】:Can I overload 'operator new' with a different return type?我可以用不同的返回类型重载“operator new”吗?
【发布时间】:2014-08-18 06:06:42
【问题描述】:

这是我的情况:我想重载“operator new”,以便将我的对象分配到预定义的内存缓冲区中,而不是在内存中的随机空间中分配我的对象。我希望能够将此缓冲区保存到文件中并在将来加载它,所以我想使用句柄而不是指针。理想情况下,我想要的是让“operator new”返回一个句柄,我可以使用该句柄直接进入对象在其缓冲区中的位置。是否可以在 C++(11) 中做到这一点?如果没有,我最好的选择是什么?

【问题讨论】:

  • 为什么不把构建对象的信息存储在文件中呢?我对句柄一无所知,因为这与 C++ 无关,但您仍然可以返回一个普通指针,当您读取文件时将内容复制到缓冲区然后简单地转换它......这确实是一个未定义的行为还有一个非常简单的方法来破解你的程序......
  • 因为我希望能够将整个系统一次保存到一个文件中,而不必序列化每个最后一个指针以获取实际上可能是数十万甚至数十万个引用。通过使用句柄(存储对象的数组的索引),我可以在它们发生之前避免无数的序列化错误。
  • 如果每个对象都自己序列化并且你有一个反序列化构造函数,那么这不是问题。根据您的定义,您的句柄是指针的偏移量,因此指针可以完成完全相同的工作。
  • @Geoffroy 不,如果对象中有任何虚函数,这仍然是个问题。所需的空间量因 CPU 平台和编译器而异,填充也是如此。如果它在 32 位和 64 位处理器上运行,那就更糟了。您永远不想将对象直接写入文件。
  • @GabeSechan 这就是我谈论存储信息以构造对象的原因。

标签: c++ operator-overloading new-operator


【解决方案1】:

Afaik 您无法更改 new 运算符的返回类型。对于您的场景,您可以尝试以下方法:

  1. 定义一个Handle(或Handle<T>,如果您需要一种以上类型的句柄)类,它在内部将索引存储到您的分配区域(即Handle有一个成员变量@987654325 @)。 Handle 类需要在内部以某种方式访问​​您的分配子系统,即它需要知道实际存储区域(缓冲区)的位置。

  2. Handle 定义一个构造函数,将指针(由您的 new 实现返回)作为参数并从中计算索引(例如,通过减去存储区域的开头)

    李>
  3. 还为 Handle 类定义解引用运算符 (operator *),返回对“已处理”对象的引用(例如,通过将索引添加到存储区域的开头...)

  4. 在您的代码中,始终使用Handle<T> 而不是指向T 的指针,至少在您实际存储句柄/指针的每个位置。

    李>

这样,当您对存储区域进行序列化/反序列化时,只会将索引写入磁盘。使用Handle 类与使用指针相同。实际指针的计算将在内部完成。

当然,这会带来一些性能损失,因为不是直接使用指针,而是总会有一些计算。这也可能会影响编译器可以完成的优化。最小化此性能问题的一个想法是实现从Handle<T>T* 的转换运算符,因此对于大量使用单个句柄/指针的代码片段,您可以轻松“预计算”指针并在整个代码中使用它.

【讨论】:

    【解决方案2】:

    我知道一些可能对你有帮助的东西..试试这个..

    标准 C++ 还支持 new 的第二个版本,称为放置 new,它在预分配的存储上构造一个对象。为了让它工作,我们必须提供我们希望分配对象的地址作为指针参数:

    (my_class= new (place) Myclass);

    那么为什么要使用新展示位置?新位置对于在预分配的内存块中构造对象很有用。这绕过了 operator new 的工作,允许构造对象的人选择它被初始化的内存。如果您想使用一个内存池来构造某个类的某些对象,但又不想为整个类重载 operator new,则可以这样做。

    【讨论】:

    • 我认为这里的问题是当 OP 存储指向已创建对象的指针时(例如将对象链接在一起)。当他简单地序列化所有分配对象的整个内存块时,反序列化后指针将无效,因为反序列化的内存块可能位于另一个位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    相关资源
    最近更新 更多