Перегрузка нового оператора и наследования - PullRequest
0 голосов
/ 28 марта 2012

Я знаю, что, возможно, это не лучший дизайн в мире, но мне интересен ответ без какой-либо практической причины.

Предположим, у меня есть два класса с перегруженными новыми методами:

class Base {
public:
operator void* new(size_t);
};

class Child : public Base {
public:
operator void* new(size_t); //THIS, i would like this to be the "original" new.
};

operator void* Base::new(size_t) {
//...
return new Child;
//...
}

Я бы хотел, чтобы Child :: new работал как оригинальный новый, поэтому я мог бы избежать использования malloc.

Есть ли способ сделать это?

Спасибо вперед!

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Это не правильный дизайн. operator new функция должна вернуть необработанную память, а не построенный объект. Если ваша цель для вызов new Base для фактического создания нового Child, это не может быть сделано в C ++; обычное решение состоит в том, чтобы обеспечить фабричный метод в Base; например:

class Base
{
    //  Ban the expression `new Base`...
    void* operator new(size_t);
protected:
    virtual ~Base();  //  Ban instances on the stack.

public:
    static Base* create(/*...*/);
    //  ...
};

Затем в исходном файле:

class Child : public Base
{
    //  ...
};

Base* Base::create(/*...*/)
{
    return ::new Child(/*...*/);
}

(Обратите внимание, что приватный operator new не полностью запрещает код клиента от использования оператора new, так как всегда можно написать ::new Base.)

Кроме объявления частного operator new о запрете прямого распределения, единственное использование operator new членов - это выделение экземпляров из конкретный бассейн; в этом случае вам также нужен член operator delete функция, чтобы освободить их в бассейн.

0 голосов
/ 28 марта 2012

Вы всегда можете получить доступ к global operator new, используя синтаксис

return ::operator new( sizeof Child );

Обратите внимание на унарный оператор области видимости.Этот синтаксис игнорирует все члены класса и пространства имен и будет работать в пределах Base::operator new или Child::operator new.

Чтобы выделить и инициализировать объект без использования членов класса / пространства имен, используйте

::new Child

Помимо этого ... да, член operator new обычно имеет серьезный запах кода.

...