重载放置新运算符,具有数据成员初始化以及与普通新运算符的差异

  • 本文关键字:运算符 数据成员 重载 初始化 c++
  • 更新时间 :
  • 英文 :


我正在编写一个重载版本的放置新,并希望在函数中初始化一个整数数据成员。

#include <cstdlib>
#include <new>
struct A {
    int i;
    void* operator new(size_t, void *p, int x) { return p; }
};
int main() {
    A* pa = new(malloc(sizeof(A)), 10) A;
    pa->~A();
    delete pa;
}

我想知道如何在上面的代码中做到这一点。也

class A {
public:
    static int* p;
    void* operator new(size_t sz, unsigned int val) {
        p = (int*) malloc(sizeof(val));
        *p = val;
    }
};
int* A::p;
int main() {
    A *p= new (10) A(); // calls overloaded new with initialization and not placement new
    cout << *(p->p) << endl; // Ans: 10
}

在上面的代码中,语法看起来类似于放置新,但它调用重载的新版本。那么编译器如何区分重载放置 new 和运算符 new?这是基于参数类型(即)void*吗?如果有一个 void* 的数据成员,并且应该通过 void* 参数对其进行初始化,该怎么办?编译器如何处理这个问题?

那么编译器如何区分重载放置 new 和运算符 new?

其实不然。放置新表达式使用与放置参数匹配的参数调用 operator new 重载(如果存在此类重载)。所以标准放置新

new (p) A;

调用在 <new> 中声明的重载

void* operator new(size_t, void*);

而具有不同参数类型的表达式会调用重载,因为类型匹配。

这是基于参数类型(即)void*吗?

是的,这正是它的工作原理。

如果有一个void*的数据成员并且应该通过 void* 参数初始化它怎么办?

数据成员应由构造函数初始化,而不是operator new。只有在初始化对象之前控制内存的分配方式时,才应覆盖operator new

不要这样做。放置(如"额外参数",而不是"无实际分配")new用于分配内存。初始化是构造函数的用途。

尽管奇怪且不太可能,但从技术上讲,C++ 实现没有理由不能包含擦除新实现返回的内存区域的代码,然后再初始化该区域中的对象。它可以将其擦除为"全零"或一些调试位模式。

相关内容

  • 没有找到相关文章