gpt4 book ai didi

c++ - 通过类中重载的 operator new 返回不同的类指针

转载 作者:行者123 更新时间:2023-11-30 02:52:53 26 4
gpt4 key购买 nike

假设我有这个示例代码:

class A
{
public:
static void* operator new(size_t sz);

private:
int xA;
float yA;
};

class B : public A
{
private:
int xB;
float yB;
};

void* A::operator new(size_t sz)
{
void* ptr = (void*)new B();
return ptr;
}

int main()
{
B* b = (B*) new A();
// Use b ..
delete b;
return 0;
}

这里将按顺序调用构造函数(在 VS2012 中测试):

  • 构造函数
  • B构造函数
  • 构造函数

前两个构造函数调用是因为重载的operator new函数中的new B()。但是随后将在函数返回的指针上再次调用 A 构造函数,因为重载的 operator new 应该返回一个指向空闲内存的指针(而不创建对象),因此再次调用构造函数。

如果我在此示例中使用指针 b,这是未定义的行为吗?

最佳答案

您发布的代码具有无限递归,因为您调用A::operator new 来自 A::operator new;类 BA 继承了 operator new

除此之外,你还欺骗了编译器,这会导致 undefined行为。在 new A 之后,您有一个指向对象的指针类型是 A。您可以合法地将其地址转换为 B*,但是您对 B* 所能做的就是将它转换回 A*;其他任何事情都是未定义的行为。

并且不清楚您要使用 new 实现什么
A::operator new 中的 B
。编译器会考虑任何内存
作为原始内存从 operator new 返回;在这种情况下,它
会在其中构造一个A对象,从那时起,所有
你有一个 A 对象。任何将其用作 B 的尝试
对象是未定义的行为。 (当然,如果你真的
需要销毁在 A::operator new 中创建的 B,你不能
因为你已经覆盖了它。



最后:您不必将operator new 声明为static
它隐含地是,并且不写 static 是惯用的
这个案例。同样,当将new B的结果赋值给
一个void*,转换是惯用的,不是惯用的
使其明确。 (最好避免 C 风格
转换,因为它们隐藏了太多错误。)








关于c++ - 通过类中重载的 operator new 返回不同的类指针,我们在Stack Overflow上找到一个类似的问题:

https://stackoverflow.com/questions/18466620/




26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com