正确地重载new/delete和new[]/delete[]

5
这是对我之前问题的跟进,使用malloc初始化类。该问题上的被接受的答案在avr-gcc上起作用并给了我new/delete,但我的重载new delete在常规gcc上出现了问题,那么正确的重载new delete的方法是什么呢?所有我的类都派生自一个公共基类,因此理想情况下,我只想为我的对象覆盖new delete,以便它不会干扰stl stdlib等。

1
请参阅此常见问题解答条目:https://dev59.com/62855IYBdhLWcg3wUCWC#4421791。 - sbi
我很好奇 - 那个链接的解决方案会带来什么破坏? - Robᵩ
2个回答

8
'Object'基类内部可以重载'new'和'delete'。因此,这仅适用于该层次结构。
class Object {
public:
  void* operator new (size_t size);
  void operator delete (void *p);
};

class Derived : public Object {
// uses the above versions of new/delete
};

[注意:这对你来说是一个额外的优势,因为你所有的类都是从一个公共的Object类派生出来的(正如你在问题和链接中提到的)]

没有通用的"Object"基类。你可能在想Java/C#领域。 :) - Billy ONeal
@Billy,OP在他的问题中提到“我的所有类都派生自一个共同的基类”,并且在他的链接问题中将其命名为“Object”。 - iammilind

3

只在您自己的类中而不是全局范围内重载 newdelete
例如:如果您的公共类名为YourClass,可以按以下方式重载它们:

void *YourClass::operator new(size_t size)
{
    void *p;
    cout << "In overloaded new.";
    p =  malloc(size);
    if(!p) 
    {
        throw std::bad_alloc;  //Throw directly than with named temp variable
    }
    return p;
}

void YourClass::operator delete(void *p)
{
    cout << "In overloaded delete.\n";
    free(p);
}

void *YourClass::operator new[](size_t size)
{
    void *p;
    cout << "Using overload new[].\n";
    p =  malloc(size);
    if(!p) 
    {
        throw std::bad_alloc;
    }
    return p;
}

void YourClass::operator delete[](void *p)
{
    cout << "Free array using overloaded delete[]\n";
    free(p);
}

所有从 YourClass 派生的类都可以使用这些重载的 newdelete 运算符。


为什么不直接使用 throw std::bad_alloc;?没有必要为此创建一个命名变量。 - Billy ONeal
@Billy ONeal:已更正。你抓住了我在编辑第一个版本之前的瞬间 :) - Alok Save
@Hamza Yerlikaya:由于您专门为自己的类重载了它们,因此这些运算符仅在您的类的对象上调用。所有其他对象将使用全局new和delete。如果您不需要异常,可能应该重载nothrow版本的new。 - Alok Save

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