Перегрузка глобального оператора new (не POD) - PullRequest
0 голосов
/ 01 февраля 2019

Рассмотрим следующий пример:

void * operator new(size_t size)
{
    void * p = malloc(size);
    //Error handling supressed...
    return p;
}

void operator delete(void * p)
{
    free(p);
}

class foo
{
public:
    foo() { baz = 4234; }
    int baz;
};

class bar
{
public:
    bar() { np = new foo(); }
    ~bar() { delete np; }
    foo* np = nullptr;
};

int main(int argc, char* argv[])
{
    bar * a = new bar();
    printf("%d\n", (*a).np->baz);
    delete a;
    return 0;
}

Я не понимаю, почему это работает.Как конструктор может быть вызван в этих обстоятельствах?Ни ID класса POD (Plain old data), у них есть конструктор и деструктор!static_assert дает мне foo или bar не POD, поэтому ...

Почему printf выводит значение 4234 на консоль?Что происходит?Разве это не должно дать мне что-то неожиданное?Я использую компилятор visual studio 15.

1 Ответ

0 голосов
/ 01 февраля 2019

Согласно [class.ctor] / 8 , конструкторы по умолчанию вызываются для создания объектов класса с динамической продолжительностью хранения, созданных новым выражением, в котором новый инициализатор опущен (не имеет значения, еслиэто значение по умолчанию operator new или пользовательское значение operator new).

Если вы не предоставите никаких конструкторов для класса, компилятор всегда будет объявлять конструктор по умолчанию в качестве встроенного открытого члена.И если неявно объявленный конструктор по умолчанию не определен как удаленный, i t определен .

Таким образом, конструкторы по умолчанию вызываются для foo и bar в этом случае.

...