用C++替换delete关键字,误传信息

9

我正在尝试解决一个类中包含SSE优化成员的16字节对齐问题,并且已经解决了。但令我困扰的是,我在许多在线示例中发现了一行代码,这行代码对我来说似乎完全是多余的,但在许多地方都重复出现。

public:
void* operator new (size_t size)throw (std::bad_alloc)
{
    void * p = _aligned_malloc(size, 16);
    if (p == 0)  throw std::bad_alloc();
    return p; 
}

void operator delete (void *p)
{
    Camera* pC = static_cast<Camera*>(p);
    _aligned_free(p);
}

该问题所涉及的行是:
Camera* pC = static_cast<Camera*>(p);

由于 pC 从未被引用并在函数结束时超出范围,那么这样做的意义是什么?我尝试将该行删除,但似乎没有任何区别,然而这一行出现在很多示例中!我是否错过了一些非常明显的东西,或者是盲目地从示例复制了一个异常代码行,并在许多“教程”中普遍存在?


5
我可能这样做的原因之一是为了协助调试。通过在“_aligned_free(p);”上设置断点,我可以检查Camera * pC对象。 - Martin James
2
如果示例始终为“相机”,那么肯定是从教程复制的。不管是盲目地还是其他方式。 - Steve Jessop
@Martin:没错,但如果这是教程中这行代码的意图,那么教程应该明确说明。特别是因为初学者可能不会立即意识到pC指向的“对象”已经被销毁,因此他们的表现可能与他们预期的不太一样。 - Steve Jessop
2
重载全局的operator newoperator delete几乎肯定不是一个好主意。此外,注意您的operator new是有问题的,它在抛出异常之前应该按顺序调用所有的new_handler。/编辑:忘记了评论的第一部分,我没有注意到这是在一个类内部。评论的第二部分仍然正确。 - Konrad Rudolph
4
也许你应该链接到包含代码的三四个地方。评论整个教程部分可能比评论几行看似不协调的代码更容易。正如Konrad所说,那个operator new本来就很靠不住,所以找另一个教程可能会更好。 - Steve Jessop
显示剩余7条评论
2个回答

2
对象一旦进入析构函数,其生命周期就结束了,因此你不能对这个指针做太多事情。可以安全地删除Camera* pC = static_cast<Camera*>(p);这一行,并且这行代码出现在教程中的唯一原因是许多人只是简单地复制粘贴它而没有真正思考它是如何工作的。
下面是您delete()的干净和正确的代码:
void operator delete (void *p)
{
    _aligned_free(p);
}

0

正如在您的问题的许多评论中所讨论的那样,以下行确实是多余的:

Camera* pC = static_cast<Camera*>(p);  // Just an unused variable

即使p之前是Camera*类型(其他可能性是子类,如Canon*Sony*Nikon*),你仍然不能对pC做太多事情,因为Camera::~Camera()应该已经被调用了。在此之后会调用operator delete

P.S.:我还没有遇到过将指针转换为特定类的做法,但如果你在教程中遇到这样的建议,你可能需要改变它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接